在我的一个游戏中,像蛇一样,我有一个错误,其中部分应该0.125f
分开,但相反,它们之间的距离与第一和第二部分之间的距离相同
我认为相关的代码:
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;
}
}
块的移动可能编码很糟糕,因为我相当新,任何一般提示和清理通常也是受欢迎的。这些块正在围绕一个球体移动,因此可能是奇怪的看似运动代码。
答案 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。