新增拆除功能
This commit is contained in:
@@ -30,15 +30,15 @@ RectTransform:
|
||||
m_GameObject: {fileID: 5156684866132484758}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalScale: {x: -1, y: -1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0.0068, y: 0.0276}
|
||||
m_SizeDelta: {x: 1.6012, y: 1.6425}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 2, y: 2}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &4716682777183481428
|
||||
CanvasRenderer:
|
||||
@@ -90,6 +90,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: e072592968a98434d9dbfe8277602f9b, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
offset: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &6191094306318057957
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1368,7 +1368,7 @@ Camera:
|
||||
far clip plane: 1000
|
||||
field of view: 34
|
||||
orthographic: 1
|
||||
orthographic size: 5
|
||||
orthographic size: 4.88
|
||||
m_Depth: -1
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
|
||||
@@ -135,63 +135,88 @@ public class Plug : MonoBehaviour, IDragHandler, IPointerDownHandler, IPointerUp
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPointerUp(PointerEventData eventData)
|
||||
public void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
if (!IsActive || IsInDialogue)
|
||||
{
|
||||
if (!IsActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (IsInDialogue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
isDragging = false;
|
||||
image.raycastTarget = true;
|
||||
// 通知 DialogueManager 结束拖拽
|
||||
DialogueManager.Instance.SetDragging(false);
|
||||
|
||||
float closestDistance = Mathf.Infinity;
|
||||
Socket closestSocket = null;
|
||||
|
||||
Socket[] sockets = FindObjectsOfType<MonoBehaviour>().OfType<Socket>().ToArray();
|
||||
|
||||
foreach (Socket socket in sockets)
|
||||
{
|
||||
float distance = Vector3.Distance(transform.position, socket.GetPosition());
|
||||
|
||||
if (distance < closestDistance)
|
||||
{
|
||||
closestDistance = distance;
|
||||
closestSocket = socket;
|
||||
}
|
||||
}
|
||||
|
||||
float snappingRange = 1f; // You might need to adjust this for WorldSpace Canvas
|
||||
if (closestSocket != null && closestDistance <= snappingRange)
|
||||
{
|
||||
currentSocket = closestSocket;
|
||||
currentSocket.InsertPlug(this);
|
||||
OnPlugInserted?.Invoke(this); // 触发插入事件
|
||||
transform.position = currentSocket.GetPosition();
|
||||
plugSprite.enabled = false;
|
||||
//transform.rotation = startRotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
transform.DOMove(startPosition, 0.1f).OnComplete(() =>
|
||||
{
|
||||
//transform.rotation = startRotation;
|
||||
initialSocket.InsertPlug(this);
|
||||
OnPlugInserted?.Invoke(this); // 触发插入事件
|
||||
plugSprite.enabled =false; // Make the plug sprite disappear when it is inserted into the initial socket.
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
isDragging = false;
|
||||
image.raycastTarget = true;
|
||||
|
||||
// 通知 DialogueManager 结束拖拽
|
||||
DialogueManager.Instance.SetDragging(false);
|
||||
|
||||
// 通过射线检测来检查是否有Socket
|
||||
PointerEventData pointerEventData = new PointerEventData(EventSystem.current)
|
||||
{
|
||||
position = eventData.position
|
||||
};
|
||||
|
||||
List<RaycastResult> raycastResults = new List<RaycastResult>();
|
||||
GraphicRaycaster graphicRaycaster = GameObject.Find("FaceCanvas").GetComponent<GraphicRaycaster>();
|
||||
graphicRaycaster.Raycast(pointerEventData, raycastResults);
|
||||
// 查找是否有Socket被检测到
|
||||
Socket targetSocket = raycastResults
|
||||
.Where(result => result.gameObject.GetComponent<Socket>() != null)
|
||||
.Select(result => result.gameObject.GetComponent<Socket>())
|
||||
.FirstOrDefault();
|
||||
|
||||
if (targetSocket != null)
|
||||
{
|
||||
// 插入到找到的Socket
|
||||
currentSocket = targetSocket;
|
||||
currentSocket.InsertPlug(this);
|
||||
OnPlugInserted?.Invoke(this); // 触发插入事件
|
||||
transform.position = currentSocket.GetPosition();
|
||||
plugSprite.enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 没有找到有效的Socket,将插头移动回原位置
|
||||
transform.DOMove(startPosition, 0.1f).OnComplete(() =>
|
||||
{
|
||||
initialSocket.InsertPlug(this);
|
||||
OnPlugInserted?.Invoke(this); // 触发插入事件
|
||||
plugSprite.enabled = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OnDrawGizmosSelected()
|
||||
{
|
||||
Gizmos.color = Color.yellow;
|
||||
float snappingRange = 1.0f; // You might need to adjust this for WorldSpace Canvas
|
||||
Gizmos.DrawWireSphere(transform.position, snappingRange);
|
||||
}
|
||||
private bool IsSocketBlocked(Socket socket)
|
||||
{
|
||||
// 获取Socket的屏幕位置
|
||||
Vector2 socketPosition = RectTransformUtility.WorldToScreenPoint(Camera.main, socket.GetComponent<RectTransform>().position);
|
||||
|
||||
// 创建PointerEventData进行射线检测
|
||||
PointerEventData pointerEventData = new PointerEventData(EventSystem.current)
|
||||
{
|
||||
position = socketPosition
|
||||
};
|
||||
|
||||
// 使用GraphicRaycaster检测遮挡
|
||||
GraphicRaycaster graphicRaycaster = GameObject.Find("FaceCanvas").GetComponent<GraphicRaycaster>();
|
||||
List<RaycastResult> results = new List<RaycastResult>();
|
||||
graphicRaycaster.Raycast(pointerEventData, results);
|
||||
|
||||
// 如果检测到其他UI元素遮挡,返回true
|
||||
foreach (var result in results)
|
||||
{
|
||||
if (result.gameObject != socket.gameObject)
|
||||
{
|
||||
return true; // 被遮挡
|
||||
}
|
||||
}
|
||||
|
||||
return false; // 未被遮挡
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using DG.Tweening;
|
||||
using System.Drawing; // 需要引入 DOTween 命名空间
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class Module : MonoBehaviour, IPointerClickHandler
|
||||
{
|
||||
public RectTransform faceCanvas; // 需要移动和缩放的面板
|
||||
public Vector3 repairCanvasPosition; // 维修模式下的面板位置
|
||||
public Vector3 originalCanvasPosition; // 原始面板位置
|
||||
public float repairCanvasScale = 1.5f; // 维修模式下的面板缩放比例
|
||||
public float animationDuration = 0.5f; // 动画持续时间
|
||||
|
||||
public GameObject screwsContainer; // 螺丝的父对象
|
||||
public RectTransform targetArea; // 拖拽的目标区域,用于判定维修完成
|
||||
|
||||
private bool isRepairMode = false;
|
||||
private bool canDrag = false;
|
||||
private Vector3 initialPosition;
|
||||
|
||||
public Graphic socketToEnable;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
initialPosition = transform.position;
|
||||
originalCanvasPosition = faceCanvas.position;
|
||||
socketToEnable.raycastTarget=false;
|
||||
EnableScrewsInteraction(false);
|
||||
}
|
||||
|
||||
public void StartRepairIfToolIsScrewdriver(Tool tool)
|
||||
{
|
||||
EnterRepairMode();
|
||||
}
|
||||
|
||||
public void EnterRepairMode()
|
||||
{
|
||||
isRepairMode = true;
|
||||
|
||||
// 使用 DOTween 对 Canvas 的位置和缩放进行平滑过渡
|
||||
faceCanvas.DOMove(repairCanvasPosition, animationDuration)
|
||||
.SetEase(Ease.OutQuad) // 移动面板
|
||||
.OnComplete(() => EnableScrewsInteraction(true)); // 动画完成后才启用交互
|
||||
|
||||
faceCanvas.DOScale(repairCanvasScale, animationDuration)
|
||||
.SetEase(Ease.OutQuad); // 缩放面板
|
||||
}
|
||||
|
||||
public void ExitRepairMode()
|
||||
{
|
||||
isRepairMode = false;
|
||||
|
||||
// 使用 DOTween 对 Canvas 的位置和缩放进行平滑过渡
|
||||
faceCanvas.DOMove(originalCanvasPosition, animationDuration)
|
||||
.SetEase(Ease.InQuad)
|
||||
.OnComplete(() => EnableScrewsInteraction(false)); // 动画完成后禁用交互
|
||||
|
||||
faceCanvas.DOScale(1f, animationDuration)
|
||||
.SetEase(Ease.InQuad); // 恢复面板缩放
|
||||
ResetModulePosition();
|
||||
ToolManager.Instance.ShowToolBoxAfterTask();
|
||||
socketToEnable.raycastTarget=true;
|
||||
}
|
||||
|
||||
private void EnableScrewsInteraction(bool isEnabled)
|
||||
{
|
||||
foreach (Transform screw in screwsContainer.transform)
|
||||
{
|
||||
screw.GetComponent<Screw>().enabled = isEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetModulePosition()
|
||||
{
|
||||
transform.position = initialPosition;
|
||||
canDrag = false; // 禁用拖拽,防止未拆完螺丝时拖动
|
||||
}
|
||||
|
||||
public void EnableDragging()
|
||||
{
|
||||
canDrag = true;
|
||||
}
|
||||
|
||||
public void CheckAllScrews()
|
||||
{
|
||||
bool allDropped = true;
|
||||
foreach (Transform screw in screwsContainer.transform)
|
||||
{
|
||||
if (screw.gameObject.activeSelf)
|
||||
{
|
||||
allDropped = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (allDropped)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
CompleteRepair();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
// 只有在玩家已获得工具且当前工具是螺丝刀时,才尝试进入维修模式
|
||||
if (ToolManager.Instance.HasTool)
|
||||
{
|
||||
ToolManager.Instance.TryStartRepairMode(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("No tool");
|
||||
}
|
||||
}
|
||||
|
||||
private void CompleteRepair()
|
||||
{
|
||||
Debug.Log("维修完成!");
|
||||
ExitRepairMode();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8bfaef6036f6054389a98770c3afb4d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,42 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
public class Screw : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
|
||||
{
|
||||
private float requiredRotation = 360f * 2; // 需要旋转的总角度(例如3圈)
|
||||
private float rotationAmount = 0f;
|
||||
private bool isPressed = false;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (isPressed)
|
||||
{
|
||||
float rotationSpeed = 360f; // 每秒旋转的角度
|
||||
float deltaRotation = rotationSpeed * Time.deltaTime;
|
||||
rotationAmount += deltaRotation;
|
||||
transform.Rotate(Vector3.forward, deltaRotation);
|
||||
|
||||
if (rotationAmount >= requiredRotation)
|
||||
{
|
||||
Drop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Drop()
|
||||
{
|
||||
gameObject.SetActive(false); // 螺丝掉落,可以替换成掉落动画
|
||||
// 检查父物体的所有螺丝状态
|
||||
transform.parent.parent.GetComponent<Module>().CheckAllScrews();
|
||||
}
|
||||
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
isPressed = true;
|
||||
}
|
||||
|
||||
public void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
isPressed = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c5ca7a8248fdb243aae486136ae3bb8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -5,49 +5,45 @@ using DG.Tweening;
|
||||
|
||||
public class Screwdriver : Tool
|
||||
{
|
||||
private int rotationCount = 0;
|
||||
private int requiredRotations = 5;
|
||||
private bool isFixing = false; // 是否在维修状态
|
||||
// private int rotationCount = 0;
|
||||
// private int requiredRotations = 5;
|
||||
// private bool isFixing = false; // 是否在维修状态
|
||||
|
||||
public override void UseTool(Vector3 targetPosition)
|
||||
{
|
||||
// 检查是否在维修状态
|
||||
if (isFixing && IsOverScrewSlot(targetPosition))
|
||||
{
|
||||
StartRemoveScrew();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void StartFixMode()
|
||||
{
|
||||
isFixing = true; // 设置为维修模式
|
||||
}
|
||||
// public void StartFixMode()
|
||||
// {
|
||||
// isFixing = true; // 设置为维修模式
|
||||
// }
|
||||
|
||||
private bool IsOverScrewSlot(Vector3 position)
|
||||
{
|
||||
// 假设使用碰撞检测或其他方法确认是否靠近螺丝槽位
|
||||
// 可以在此实现实际的检测逻辑
|
||||
return true; // 简单返回true用于测试
|
||||
}
|
||||
// private bool IsOverScrewSlot(Vector3 position)
|
||||
// {
|
||||
// // 假设使用碰撞检测或其他方法确认是否靠近螺丝槽位
|
||||
// // 可以在此实现实际的检测逻辑
|
||||
// return true; // 简单返回true用于测试
|
||||
// }
|
||||
|
||||
private void StartRemoveScrew()
|
||||
{
|
||||
// 螺丝旋转动画
|
||||
transform.DORotate(new Vector3(0, 0, -90), 0.5f, RotateMode.LocalAxisAdd).OnComplete(() =>
|
||||
{
|
||||
rotationCount++;
|
||||
if (rotationCount >= requiredRotations)
|
||||
{
|
||||
RemoveScrew();
|
||||
}
|
||||
});
|
||||
}
|
||||
// private void StartRemoveScrew()
|
||||
// {
|
||||
// // 螺丝旋转动画
|
||||
// transform.DORotate(new Vector3(0, 0, -90), 0.5f, RotateMode.LocalAxisAdd).OnComplete(() =>
|
||||
// {
|
||||
// rotationCount++;
|
||||
// if (rotationCount >= requiredRotations)
|
||||
// {
|
||||
// RemoveScrew();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
private void RemoveScrew()
|
||||
{
|
||||
Debug.Log("Screw removed");
|
||||
rotationCount = 0;
|
||||
// 可以加入螺丝掉落的逻辑,比如销毁对象或改变其状态
|
||||
}
|
||||
// private void RemoveScrew()
|
||||
// {
|
||||
// Debug.Log("Screw removed");
|
||||
// rotationCount = 0;
|
||||
// // 可以加入螺丝掉落的逻辑,比如销毁对象或改变其状态
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class ScrewsManager : MonoBehaviour
|
||||
{
|
||||
public Module module;
|
||||
|
||||
public void CheckAllScrews()
|
||||
{
|
||||
bool allDropped = true;
|
||||
foreach (Transform screw in transform)
|
||||
{
|
||||
if (screw.gameObject.activeSelf)
|
||||
{
|
||||
allDropped = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (allDropped)
|
||||
{
|
||||
module.EnableDragging();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a545dd5c61ba4f44a644918c03adc3b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -6,6 +6,7 @@ using UnityEngine;
|
||||
public abstract class Tool : MonoBehaviour
|
||||
{
|
||||
//public string toolName;
|
||||
public Vector3 offset;
|
||||
protected bool isFollowingMouse = false;
|
||||
public bool IsFollowingMouse => isFollowingMouse; // 只读属性
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using UnityEngine.UI;
|
||||
|
||||
public class ToolManager : MonoBehaviour
|
||||
{
|
||||
public static ToolManager Instance { get; private set; }
|
||||
public GameObject toolBox; // 工具盒的UI对象
|
||||
private Tool currentTool;
|
||||
public List<GameObject> toolPrefabs;
|
||||
@@ -14,6 +15,22 @@ public class ToolManager : MonoBehaviour
|
||||
public Canvas toolCanvas;
|
||||
private bool isBoxShow = false;
|
||||
|
||||
public bool HasTool => currentTool != null; // 判断玩家是否已获得工具
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// 确保 ToolManager 只有一个实例,并且这个实例是唯一的
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(gameObject); // 如果实例已经存在,销毁当前实例
|
||||
}
|
||||
else
|
||||
{
|
||||
Instance = this; // 保持唯一实例
|
||||
//DontDestroyOnLoad(gameObject); // 不销毁这个工具管理器
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
toolBox.SetActive(false); // 初始隐藏工具盒
|
||||
@@ -28,16 +45,14 @@ public class ToolManager : MonoBehaviour
|
||||
}
|
||||
}
|
||||
}
|
||||
public void EnterFixMode(string moduleName)
|
||||
public void TryStartRepairMode(Module module)
|
||||
{
|
||||
Debug.Log($"Entering fix mode for module: {moduleName}");
|
||||
|
||||
if (currentTool != null && currentTool is Screwdriver screwdriver)
|
||||
// 如果当前工具是螺丝刀,调用Module的EnterRepairMode方法
|
||||
if (currentTool is Screwdriver)
|
||||
{
|
||||
screwdriver.StartFixMode(); // 调用螺丝刀进入维修状态
|
||||
module.StartRepairIfToolIsScrewdriver(currentTool);
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowTool(string toolName)
|
||||
{
|
||||
if (toolPrefabDictionary.TryGetValue(toolName, out GameObject toolPrefab))
|
||||
@@ -99,7 +114,7 @@ public class ToolManager : MonoBehaviour
|
||||
toolBox.SetActive(true);
|
||||
isBoxShow = true;
|
||||
|
||||
toolBox.transform.DOMoveY(-4f, 0.5f).SetEase(Ease.OutBounce);
|
||||
toolBox.transform.DOMoveY(-3.7f, 0.5f).SetEase(Ease.OutBounce);
|
||||
|
||||
// 为工具盒添加一次性点击事件
|
||||
AddToolBoxReturnEvent();
|
||||
@@ -129,7 +144,7 @@ public class ToolManager : MonoBehaviour
|
||||
|
||||
public void HideTool()
|
||||
{
|
||||
toolBox.transform.DOMoveY(-6f, 0.5f).SetEase(Ease.InBack).OnComplete(() =>
|
||||
toolBox.transform.DOMoveY(-6.3f, 0.5f).SetEase(Ease.InBack).OnComplete(() =>
|
||||
{
|
||||
toolBox.SetActive(false);
|
||||
isBoxShow = false;
|
||||
@@ -150,8 +165,11 @@ public class ToolManager : MonoBehaviour
|
||||
{
|
||||
if (currentTool != null && currentTool.IsFollowingMouse)
|
||||
{
|
||||
//Vector2 imageSize = toolImage.rect.size;
|
||||
//Cursor.visible = false;
|
||||
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
|
||||
currentTool.transform.position = new Vector3(mousePos.x, mousePos.y, 0);
|
||||
//Vector3 toolOffset=currentTool.offset;
|
||||
currentTool.transform.position = new Vector3(mousePos.x+0.75f, mousePos.y+0.75f, 0);
|
||||
}
|
||||
if(Input.GetKeyDown(KeyCode.O))
|
||||
{
|
||||
@@ -181,6 +199,7 @@ public void ReturnTool()
|
||||
|
||||
currentTool = null;
|
||||
HideTool();
|
||||
//Cursor.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user