【问题标题】:Gameobject moving oddly游戏对象奇怪地移动
【发布时间】:2019-03-03 22:31:52
【问题描述】:

我的游戏对象移动异常。

关于敌人,我有这个脚本:

public float speed = 1.0f;
private Transform target;

public void Start()
{
    var player = GameObject.FindWithTag("Player");
    target = player.transform;
}

void Update()
{
    // Move our position a step closer to the target.
    float step = speed * Time.deltaTime; // calculate distance to move
    transform.position = Vector3.MoveTowards(transform.position, target.position, step);

    // Check if the position of the cube and sphere are approximately equal.
    if (Vector3.Distance(transform.position, target.position) < 0.001f)
    {
        // Swap the position of the cylinder.
        target.position *= -1.0f;
    }
}

我用弹丸击中敌人后,它的移动速度开始变慢。弹丸背后的脚本是这样的:

    if (coll.gameObject.tag != "Player")
    {
        Destroy(gameObject);

        if ((coll.collider.GetComponent("Damageable") as Damageable) != null)
        {
            var d = coll.collider.GetComponent<Damageable>();
            d.Damage(1);
        }
    }

我添加了这个脚本,作为一个可损坏组件,但是,这个行为甚至在这个脚本激活之前就已经存在,所以我认为它不相关:

public void Damage(int damageAmount)
{
    print("Damage : " + Health + ":" + damageAmount);
    Health -= damageAmount;
    if (Health <= 0)
    {
        Destroy(gameObject);
    }
}

有什么错误的建议吗?

【问题讨论】:

  • 一:您应该在Update 之外的方法中缓存播放器转换,这样就不会每次都调用它。二:当你说“它”移动奇怪时,你是指玩家、弹丸还是被击中的敌人?
  • 是的,我最初是这样做的。我一开始就有,然后一直在课堂上。上述原因我认为这可能是由于“丢失”了玩家的位置,如果我每次都重新计算位置,它可能会修复它。可悲的是,这不是问题。我会回复并更新问题。
  • 因为 Vector3 是一个结构体,你不会失去来自player.transform的引用
  • Vector3 默认比较已经有近似值,你可能不需要它,你的方法也暗示调用Sqrt,如果你有很多对象,这可能会很昂贵。您也可以使用Vector3.SqrDistance(a, b)(a - b).sqrMagnitude,尽管我不确定第一个变体。不要称它为GetComponent(string),而是检查d != null,如果你使用C# 6,甚至可能是d?.Damage(1)target.position * -1.0 行有些奇怪,它应该怎么做?
  • 不太可能。但无论如何你都会想解决这个问题。使用字符串来引用已知类型的东西不是一个好主意。一,有大量的反射开销,二意味着它更难重构。

标签: unity3d


【解决方案1】:

科尔

我猜这是碰撞的缩写,碰撞发生在 2 个刚体上(或另一个静态碰撞器,但与问题无关),所以当子弹击中敌人时,它也会阻挡敌人的路径,即使你立即摧毁它敌人仍然会停止移动 1 帧。

所以让子弹上的对撞机成为触发器,触发器不会阻挡其他刚体。

使用OnTriggerEnter2D(或OnTriggerEnter(Collider) 用于3D 游戏)接收触摸事件。

void OnTriggerEnter2D(Collider2D other)
{
    if (other.gameObject.tag != "Player")
    {
        Destroy(gameObject);

        var d = other.GetComponent<Damageable>();
        if(d != null)
            d.Damage(1);
    }
}

【讨论】:

  • “我猜这是碰撞的缩写” - 关闭。碰撞,如..“除此之外的另一个碰撞对象”。您的回答听起来像是一个很好的解决方案。打算试一试,然后回复你。
  • 这几乎可以完美运行。您的脚本需要的唯一更改是将函数更改为 OnTriggerEnter2D(Collider2D 其他)。我会接受你的回答,但请为以后的读者改变它。
  • 对不起,我对 unity 的第一印象是 3D 引擎,我没有意识到它现在也适用于 2D。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多