Unity回合制策略游戏角色点击移动方格后偏移到错误位置问题求助
核心问题根因
- 位移API误用:
Transform.Translate()接收的是相对当前位置的偏移值,你代码中传入的是目标方格的世界坐标,导致最终位置 = 角色当前坐标 + 目标方格坐标,完全不符合预期。 - 点击事件重复触发:
OnMouseOver中使用Input.GetKey(KeyCode.Mouse0)会在按住左键的每帧都执行位移逻辑,单次点击可能触发多次位移叠加,偏移量逐次累加。 - 移动方格重复生成:
units脚本的Update方法中只要角色处于选中状态,每帧都会生成一轮可移动范围方格,同位置会堆叠大量重复MovePlate,点击时多次触发位移,同时会产生冗余性能消耗。 - 选中提示资源泄漏:选中角色时生成的
tempselect没有销毁逻辑,每次选中都会新增实例,额外占用资源。
修复代码
MovePlate.cs 修正后内容
using System.Collections; using System.Collections.Generic; using UnityEngine; public class MovePlate : MonoBehaviour { GameObject controller; public GameObject reference = null; public float x; public float y; // Start is called before the first frame update void Start() { x = this.transform.position.x; y = this.transform.position.y; } // Update is called once per frame void Update() { } public void SetReference(GameObject obj) { reference = obj; } public GameObject GetReference() { return reference; } public void OnMouseOver() { // 改用GetKeyDown只触发一次点击,直接赋值世界坐标而非相对偏移 if(Input.GetKeyDown(KeyCode.Mouse0)) { reference.transform.position = new Vector3(x, y, reference.transform.position.z); reference.GetComponent<units>().selected = false; } } }
units.cs 修正后内容
using System.Collections; using System.Collections.Generic; using UnityEngine; public class units : MonoBehaviour { public GameObject Select; public GameObject movePlate; public GameObject tempselect; public int movement; public bool selected; private bool mouseover; // Start is called before the first frame update void Start() { selected = false; mouseover = false; } // Update is called once per frame void Update() { if(selected && Input.GetKey(KeyCode.Mouse1)) { selected = false; } if(!selected) { DestroyMovePlates(); // 取消选中时销毁选中提示 if(tempselect != null) { Destroy(tempselect); tempselect = null; } } } // 把移动方格生成逻辑抽成单独方法,只在选中时调用一次 void SpawnMovePlates() { for (int i = 1; i < movement + 1; i++) { Debug.Log("Bacon"); if (this.gameObject.transform.position.x + i < 20) { GameObject mp1 = Instantiate(movePlate, new Vector3(this.gameObject.transform.position.x + i, this.gameObject.transform.position.y, -2), Quaternion.identity); mp1.GetComponent<MovePlate>().SetReference(this.gameObject); mp1.GetComponent<MovePlate>().x = this.gameObject.transform.position.x + i; mp1.GetComponent<MovePlate>().y = this.gameObject.transform.position.y; } if (this.gameObject.transform.position.x + i < 20 && this.gameObject.transform.position.y + i < 20) { GameObject mp2 = Instantiate(movePlate, new Vector3(this.gameObject.transform.position.x + i, this.gameObject.transform.position.y + i, -2), Quaternion.identity); mp2.GetComponent<MovePlate>().SetReference(this.gameObject); mp2.GetComponent<MovePlate>().x = this.gameObject.transform.position.x + i; mp2.GetComponent<MovePlate>().y = this.gameObject.transform.position.y + i; } if (this.gameObject.transform.position.y + i < 20) { GameObject mp3 = Instantiate(movePlate, new Vector3(this.gameObject.transform.position.x, this.gameObject.transform.position.y + i, -2), Quaternion.identity); mp3.GetComponent<MovePlate>().SetReference(this.gameObject); mp3.GetComponent<MovePlate>().x = this.gameObject.transform.position.x; mp3.GetComponent<MovePlate>().y = this.gameObject.transform.position.y + i; } if (this.gameObject.transform.position.x - i >= 0 && this.gameObject.transform.position.y + i < 20) { GameObject mp4 = Instantiate(movePlate, new Vector3(this.gameObject.transform.position.x - i, this.gameObject.transform.position.y + i, -2), Quaternion.identity); mp4.GetComponent<MovePlate>().SetReference(this.gameObject); mp4.GetComponent<MovePlate>().x = this.gameObject.transform.position.x - i; mp4.GetComponent<MovePlate>().y = this.gameObject.transform.position.y + i; } if (this.gameObject.transform.position.x - i >= 0) { GameObject mp5 = Instantiate(movePlate, new Vector3(this.gameObject.transform.position.x - i, this.gameObject.transform.position.y, -2), Quaternion.identity); mp5.GetComponent<MovePlate>().SetReference(this.gameObject); mp5.GetComponent<MovePlate>().x = this.gameObject.transform.position.x - i; mp5.GetComponent<MovePlate>().y = this.gameObject.transform.position.y; } if (this.gameObject.transform.position.x + i < 20 && this.gameObject.transform.position.y - i >= 0) { GameObject mp6 = Instantiate(movePlate, new Vector3(this.gameObject.transform.position.x + i, this.gameObject.transform.position.y - i, -2), Quaternion.identity); mp6.GetComponent<MovePlate>().SetReference(this.gameObject); mp6.GetComponent<MovePlate>().x = this.gameObject.transform.position.x + i; mp6.GetComponent<MovePlate>().y = this.gameObject.transform.position.y - i; } if (this.gameObject.transform.position.y - i >= 0) { GameObject mp7 = Instantiate(movePlate, new Vector3(this.gameObject.transform.position.x, this.gameObject.transform.position.y - i, -2), Quaternion.identity); mp7.GetComponent<MovePlate>().SetReference(this.gameObject); mp7.GetComponent<MovePlate>().x = this.gameObject.transform.position.x; mp7.GetComponent<MovePlate>().y = this.gameObject.transform.position.y - i; } if (this.gameObject.transform.position.x - i >= 0 && this.gameObject.transform.position.y - i >= 0) { GameObject mp8 = Instantiate(movePlate, new Vector3(this.gameObject.transform.position.x - i, this.gameObject.transform.position.y - i, -2), Quaternion.identity); mp8.GetComponent<MovePlate>().SetReference(this.gameObject); mp8.GetComponent<MovePlate>().x = this.gameObject.transform.position.x - i; mp8.GetComponent<MovePlate>().y = this.gameObject.transform.position.y - i; } } } void OnMouseOver() { if (Input.GetKeyDown(KeyCode.Mouse0)&&!selected) { tempselect = Instantiate(Select, new Vector3(this.gameObject.transform.position.x, this.gameObject.transform.position.y, -3), Quaternion.identity); selected = true; // 选中时仅生成一次移动方格 SpawnMovePlates(); } } public void DestroyMovePlates() { //Destroy old MovePlates GameObject[] movePlates = GameObject.FindGameObjectsWithTag("MovePlate"); for (int i = 0; i < movePlates.Length; i++) { Destroy(movePlates[i]); //Be careful with this function "Destroy" it is asynchronous } } }
替换代码后即可解决位移偏移、硬编码位置异常、多次移动坐标累加的问题,同时避免了重复生成对象的性能损耗。
内容的提问来源于stack exchange,提问作者user2420395
相关产品推荐
相关产品推荐

