错误的运动

时间:2017-07-10 10:37:39

标签: c# unity3d

在我的一个游戏中,像蛇一样,我有一个错误,其中部分应该0.125f分开,但相反,它们之间的距离与第一和第二部分之间的距离相同

enter image description here

我认为相关的代码:

      using UnityEngine;
        using System.Collections;
        using System.Collections.Generic;

public class SnakeHead : MonoBehaviour
{
    public float growTime = 5;
    private float moveSpeed;
    private Transform origin, prevPart = null;
    private List<GameObject> snakeBodyPartsList;
    public Mesh mesh;
    public Material material;
    private GameObject body, sphere;
    private RaycastHit hit;

    void Start()
    {
        sphere = GameObject.Find("Sphere");
        origin = new GameObject("SnakeHead Origin").transform;
        origin.parent = sphere.transform;
        transform.parent = origin;
        snakeBodyPartsList = new List<GameObject>();
        snakeBodyPartsList.Add(gameObject);
        StartCoroutine("addBodyPart");
    }

    void Update()
    {
        if (Input.GetKey(KeyCode.Escape))
        {
            Application.Quit();
        }
        foreach (GameObject part in snakeBodyPartsList)
        {
            moveSpeed = 30 + (snakeBodyPartsList.Count * 2.5f);
            if (part == gameObject)
            {
                if (Input.GetKey("a") || Input.GetKey("d"))
                {
                    var turnRate = Input.GetKey("a") ? -120 : 120;
                    part.transform.parent.Rotate(0, 0, turnRate * Time.deltaTime);
                }
                part.transform.rotation = Quaternion.LookRotation(transform.forward, part.transform.position - sphere.transform.position);
                part.transform.parent.rotation = Quaternion.AngleAxis(moveSpeed * Time.deltaTime, Vector3.Cross(part.transform.parent.position - part.transform.position, part.transform.forward)) * part.transform.parent.rotation;
            }
            else
            {
                part.transform.rotation = Quaternion.LookRotation(prevPart.transform.position, part.transform.position - sphere.transform.position);
                if (prevPart != null && Vector3.Distance(part.transform.position, prevPart.position) > 0.125f)
                {
                   // moveSpeed = moveSpeed + Vector3.Distance(part.transform.position, prevPart.position)* 100;
                    part.transform.parent.rotation = Quaternion.AngleAxis(moveSpeed * Time.deltaTime, Vector3.Cross(part.transform.parent.position - part.transform.position, -(prevPart.position - part.transform.position).normalized * 0.125f)) * part.transform.parent.rotation;
                }
            }
            returnToSurface(part);
            prevPart = part.transform;
        }
    }

    private IEnumerator addBodyPart()
    {
        yield return new WaitForSeconds(1);
        body = createNewGameObject(body, "Body " + snakeBodyPartsList.Count, null, mesh, material, snakeBodyPartsList[snakeBodyPartsList.Count - 1].transform.position, Vector3.one / 10, true, true);
        snakeBodyPartsList.Add(body);
        yield return new WaitForSeconds(Mathf.Abs(growTime - 1));
        StartCoroutine("addBodyPart");
    }

    public GameObject createNewGameObject(GameObject uGO, string Name, Transform Parent, Mesh Mesh, Material Material, Vector3 Position, Vector3 localScale, bool needsOrigin, bool needscollider)
    {
        uGO = new GameObject(Name);
        if (needsOrigin)
        {
            origin = new GameObject("BodyPart Origin " + snakeBodyPartsList.Count).transform;
            origin.parent = sphere.transform;
            uGO.transform.parent = origin;
        }
        else
        {
            uGO.transform.parent = Parent;
        }
        uGO.gameObject.AddComponent<MeshFilter>().mesh = Mesh;
        uGO.AddComponent<MeshRenderer>().material = Material;
        uGO.transform.position = Position;
        uGO.transform.localScale = localScale;
        if (needscollider)
        {
            uGO.AddComponent<BoxCollider>().size = Vector3.one;
            uGO.GetComponent<BoxCollider>().isTrigger = true;
        }
        uGO.transform.forward = transform.forward;
        uGO.transform.rotation = transform.rotation;
        return uGO;
    }

    void returnToSurface(GameObject a)
    {
        if (Vector3.Distance(a.transform.position, sphere.transform.position) > 1.05)
        {
            while (Vector3.Distance(a.transform.position, sphere.transform.position) >= 1.045)
            {
                a.transform.position = new Vector3(a.transform.position.x, a.transform.position.y, a.transform.position.z - 0.001f);
            }
        }
        else if (Vector3.Distance(a.transform.position, sphere.transform.position) < 1.04)
        {
            while (Vector3.Distance(a.transform.position, sphere.transform.position) <= 1.045)
            {
                a.transform.position = new Vector3(a.transform.position.x, a.transform.position.y, a.transform.position.z + 0.001f);
            }
        }

    }
    public List<GameObject> getPartsList()
    {
        return snakeBodyPartsList;
    }
}

块的移动可能编码很糟糕,因为我相当新,任何一般提示和清理通常也是受欢迎的。这些块正在围绕一个球体移动,因此可能是奇怪的看似运动代码。

2 个答案:

答案 0 :(得分:0)

我可能错了,但我没有足够的代表发表评论,所以我会将其作为回复邮寄给您:

由于您的问题仅在头部和第一个身体部位之间,我想象您的问题是因为第一次运行时没有设置prevPart(游戏对象的身体部位不一定是第一个要在foreach中检查)。您可能希望尝试在foreach之前处理第一个if语句,以便保证在第一次运行时正确设置所有内容。您可以将gameObject正文部分保留在列表之外,或使用if处理该情况(如本例所示)。

这样的事情:

void Update()
{
    moveSpeed = 30 + (snakeBodyPartsList.Count * 2.5f);

    // First update the head (gameObject)
    if (Input.GetKey("a") || Input.GetKey("d"))
    {
        var turnRate = Input.GetKey("a") ? -120 : 120;
        transform.parent.Rotate(0, 0, turnRate * Time.deltaTime);
    }
    transform.rotation = Quaternion.LookRotation(transform.forward, transform.position - sphere.transform.position);
    transform.parent.rotation = Quaternion.AngleAxis(moveSpeed * Time.deltaTime, Vector3.Cross(transform.parent.position - transform.position, transform.forward)) * transform.parent.rotation;
    returnToSurface(part);
    prevPart = part.transform;

    // Then update the body (snakeBodyPartsList)
    foreach (GameObject part in snakeBodyPartsList)
    {
        if (part != gameObject)
        {
            if (prevPart != null) // prevPart is already used here, so you might as well check it here instead of after the next line
            {
                part.transform.rotation = Quaternion.LookRotation(prevPart.transform.position, part.transform.position - sphere.transform.position);
                if (Vector3.Distance(part.transform.position, prevPart.position) > 0.125f)
                {
                    part.transform.parent.rotation = Quaternion.AngleAxis(moveSpeed * Time.deltaTime, Vector3.Cross(part.transform.parent.position - part.transform.position, -(prevPart.position - part.transform.position).normalized * 0.125f)) * part.transform.parent.rotation;
                }
            }
            else
            {
                Debug.Log('No prevPart in the snakeBodyPartsList foreach'); // EDIT: Might as well add something here just in case... :)
            }
            returnToSurface(part);
            prevPart = part.transform;
        }
    }
}

这有帮助吗?

PS:移动代码对我来说很好,但为了清晰起见,您可能想要给出您的幻数变量名称。

答案 1 :(得分:0)

所以,这是通过在转弯过程中将头部的移动速度减半来解决的,但是想知道为什么但是在转动时头部比身体移动得更快,导致它从身体部位拉开。感谢来自solent uni的@Bruins。