主要问题是循环
while (Vector3.Distance(transform.position,targetPosition) > 0.1f)
{
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position,targetPosition,step);
}
这一步移动了对象,因为同时没有渲染任何帧。 while
会阻塞整个线程,直到完成为止(我在这种情况下还不算太长),然后在完成后渲染帧。
此外,在注释OnGUI
中也提到,每帧被多次调用,因此情况甚至更糟。
正如我也评论过的,OnGUI
是一种遗产,您不应该再使用它,除非您确切地知道自己的工作方式和作法。
请使用UI.Button
in a Canvas
。
如果我没看错,您想在按住按钮的同时移动。
不幸的是,没有内置的Button可以处理“按下按钮时保持按下状态”之类的东西,因此您必须使用IPointerDownHandler
和IPointerUpHandler
界面。
将此类放在UI.Button
对象上
public class MoveButton : MonoBehaviour,IPointerEnterHandler,IPointerExitHandler,IPointerDownHandler,IPointerUpHandler
{
public enum Alignment
{
Global,Local
}
// Configure here the movement step per second in all three axis
public Vector3 moveStep;
// Here reference the object that shall be move by this button
public Transform targetObject;
// Configure here wether you want the movement in
// - Global = World-Space
// - Local = Object's Local-Space
public Alignment align;
private Button button;
private void Awake ()
{
button = GetComponent<Button>();
}
//Detect current clicks on the GameObject (the one with the script attached)
public void OnPointerDown(PointerEventData pointerEventData)
{
// Ignore if button is disabled
if(!button.interactible) return;
StartCoroutine (Move());
}
public void OnPointerUp(PointerEventData pointerEventData)
{
StopAllCoroutines();
}
public void OnPointerExit(PointerEventData pointerEventData)
{
StopAllCoroutines();
}
// Actually not really needed but I'm not sure right now
// if it is required for OnPointerExit to work
// E.g. PointerDown doesn't work if PointerUp is not present as well
public void OnPointerEnter(PointerEventData pointerEventData)
{
}
// And finally to the movement
private IEnumerator Move()
{
// Whut? Looks dangerous but is ok as long as you yield somewhere
while(true)
{
// Depending on the alignment move one step in the given direction and speed/second
if(align == Alignment.Global)
{
targetObject.position += moveStep * Time.deltaTime;
}
else
{
targetObject.localPosition += moveStep * Time.deltaTime;
}
// Very important! This tells the routine to "pause"
// render this frame and continue from here
// in the next frame.
// without this Unity freezes so careful ;)
yield return null;
}
}
}
或者,您可以坚持自己的代码,但可以将按钮与移动分开,例如
private bool isPressed;
private void OnGUI()
{
isPressed = GUI.Button(new Rect(165,300,150,350),"right");
}
private void Update()
{
if(!isPressed) return;
var pos = transform.position;
var targetPosition = pos + Vector3.right * 0.5f;
if (Vector3.Distance(transform.position,targetPosition) > 0.1f)
{
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position,step);
}
}
本文链接:https://www.f2er.com/3149974.html