如何修复Unity中的痉挛和bug实例化



我正在用C#在Unity中创建一个基本的台球游戏,我想做的是,如果母球在移动,球杆就会消失,一旦它再次静止,它就会重新出现在母球所在的位置。这是我迄今为止的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class stickDeplacement : MonoBehaviour
{
public bool bIsOnTheMove = false;
Vector3 lastPos;
public GameObject Stick;
void Start()
{
}

void Update()
{
var stick = Instantiate(Stick, gameObject.transform.position, gameObject.transform.rotation);
if (this.transform.position != lastPos)
{
Destroy(stick);
Debug.Log("Is moving");
}
else
{
Debug.Log("Is not moving");
}
lastPos = this.transform.position;
}

}

但实际情况是,球和球杆从一开始(当我打开并开始比赛时(就会痉挛并出现问题。我是不是遗漏了什么?

  • 这是非常低效和危险的!

    为什么每个帧都实例化一个棒,最终却在同一帧中销毁了它?如果球是静止的,你想在每帧中产生一根额外的棍子吗?

    与其一直实例化和销毁它,不如保留一个棒,只(取消(激活它。

    在您的情况下,您可以在单行中完成此操作

    bIsOnTheMove = transform.position == lastPos;
    stick.SetActive(!bIsOnTheMove);
    
  • 我也很怀疑你是否希望棍子像滚球一样旋转!当然,这将表现出尴尬的

    大多数情况下,您确实想而不是只是想克隆球的方向。例如,我会尝试确定桌子边缘与当前球的位置最近的点(遍历墙碰撞器并使用Collider.ClosestPoint(,并让棍子面向从该边缘点到球位置的方向(+可能是X中的偏移,因此默认情况下棍子稍微倾斜(。

  • 最后,无论如何,你都不想为每一帧指定旋转,因为你很可能以后希望你的用户能够旋转棍子。当球静止时,您只想应用一次

类似的东西

// The stick is not a prefab anymore but simply always exists in the scene!
[SerializeField] private Transform stick;
[SerializeField] private Vector3 eulerOffset;
[SerializeField] private Collider[] wallColliders;
public bool bIsOnTheMove;
private Vector3 lastPos;
private void Start()
{
lastPos = transform.position;
}
private void Update()
{
// is the ball currently moving?
var isMoving = transform.position == lastPos;
last Post = transform.position;
// Did this state change since the last frame?
if(bIsOnTheMove == isMoving) return;
bIsOnTheMove = isMoving;
// (de)activate the stick accordingly
stick.gameObject.SetActive(!isMoving);

// Do this ONCE when ball becomes stanionary    
if(!isMoving)
{
var ballPosition = transform.position;
// among the wall colliders find which one is closest to the ball
Vector3 closestPoint;
var smallestDistance = float.PositiveInifinity;
foreach(var wall in wallColliders)
{
var edgePoint = wall.ClosestPoint(ballPosition);
var distane = (edgePoint - ballPosition).sqrMagnitude;
if(distance < smallestDistance)
{
closestPoint = point;
smallestDistance = distance;
}
}
// then make the stick look towards the ball from that edge
var direction = ballPosition - closestPoint;
var rotation = Quaternion.LookRotation(direction);
// optional add the offset
rotation *= Quaternion.Euler(eulerOffset);

stick.rotation = rotation;    
}
}

最新更新