首先,这里是问题的视频:
link to video,这里是package
这是分层的屏幕截图:
GUN是具有脚本(空游戏对象)的父级.悬架被放到towerRotateObj上,而Gun则被放到turretRotateObj上.悬架和Gun也是空的游戏对象.它们只是某种组对象
这里的代码:
public class WeaponMover : MonoBehavIoUr
{
public Transform target;
public GameObject turretRotateObj;
public GameObject towerRotateObj;
public float maxTowerRotationSpeed = 360.0f;
public float maxTurretRotationSpeed = 360.0f;
public float smoothFactorTower = 0.125f;
public float smoothFactorTurret = 0.125f;
public float maxTowerRotation = 130.0f;
public float maxTurretRotation = 50.0f;
private Vector3 m_newRotation;
private Vector3 m_angles;
private float m_minTowerAngle;
private float m_maxTowerAngle;
private float m_minTurretAngle;
private float m_maxTurretAngle;
private float m_velTower;
private float m_velTurret;
private bool m_isTransNecTower = false;
private bool m_isTransNecTurret = false;
// initialization
void Start()
{
m_newRotation = Vector3.zero;
m_angles = Vector3.zero;
m_maxTowerAngle = towerRotateObj.transform.eulerAngles.y + maxTowerRotation/2;
m_minTowerAngle = towerRotateObj.transform.eulerAngles.y - maxTowerRotation/2;
m_maxTurretAngle = turretRotateObj.transform.eulerAngles.z + maxTurretRotation/2;
m_minTurretAngle = turretRotateObj.transform.eulerAngles.z - maxTurretRotation/2;
// check if rotation happens between 0/360
// tower
if(m_minTowerAngle <= 0.0f)
m_minTowerAngle += 360.0f;
if(m_maxTowerAngle >= 360.0f)
m_maxTowerAngle -= 360.0f;
if(m_minTowerAngle > m_maxTowerAngle)
m_isTransNecTower = true;
// turret
if(m_minTurretAngle <= 0.0f)
m_minTurretAngle += 360.0f;
if(m_maxTurretAngle >= 360.0f)
m_maxTurretAngle -= 360.0f;
if(m_minTurretAngle > m_maxTurretAngle)
m_isTransNecTurret = true;
}
void Update()
{
m_newRotation = Quaternion.LookRotation(target.position - towerRotateObj.transform.position).eulerAngles;
m_angles = towerRotateObj.transform.rotation.eulerAngles;
towerRotateObj.transform.rotation = Quaternion.Euler(m_angles.x,
ClampAngle(Mathf.SmoothdampAngle(m_angles.y,
m_newRotation.y - 90.0f,
ref m_velTower,
smoothFactorTower,
maxTowerRotationSpeed), m_minTowerAngle, m_maxTowerAngle, m_isTransNecTower),
m_angles.z);
m_newRotation = Quaternion.LookRotation(target.position - turretRotateObj.transform.position).eulerAngles;
m_angles = turretRotateObj.transform.rotation.eulerAngles;
turretRotateObj.transform.rotation = Quaternion.Euler(m_angles.x,
m_angles.y,
ClampAngle(Mathf.SmoothdampAngle(m_angles.z,
-m_newRotation.x,
ref m_velTurret,
smoothFactorTurret,
maxTurretRotationSpeed), m_minTurretAngle, maxTurretRotation, m_isTransNecTurret));
}
private float ClampAngle(float angle, float min, float max, bool isTranslationNecessary)
{
if(!isTranslationNecessary)
{
if(angle < min )
return min;
if(angle > max)
return max;
}
else
{
if(angle > max && angle < min)
{
if(min - angle > angle - max)
return max;
else
return min;
}
}
return angle;
}
}
因此,它具有类似的设置,例如坦克的塔和枪.
我已经发布了该问题here,但似乎很少有人看到该帖子.谢谢.
更新:
m_newRotation = Quaternion.LookRotation(m_target.transform.position - towerRotateObj.transform.position).eulerAngles;
m_newRotation.y -= 90f;
m_angles = towerRotateObj.transform.rotation.eulerAngles;
towerRotateObj.transform.rotation = Quaternion.Euler(m_angles.x, m_newRotation.y, m_angles.z);
m_newRotation = Quaternion.LookRotation(m_target.transform.position - turretRotateObj.transform.position).eulerAngles;
m_angles = turretRotateObj.transform.rotation.eulerAngles;
turretRotateObj.transform.rotation = Quaternion.Euler(m_angles.x, m_angles.y, -m_newRotation.x);
问题保持不变:(
解决方法:
所以我的猜测是,万向节锁,就像在其他答案中所说的那样.但是,考虑到您正在将四元数传递给欧拉,反之亦然,因此我不确定我是否会尝试解决该问题.如果必须这样做,我就不会像您那样做,因为在对象之间使用四元数进行育儿就等于头痛不已.
首先,当您为对象做父母时,您没有使用该功能!这是Unity的一项非常可靠的功能.统一育儿:http://docs.unity3d.com/Documentation/ScriptReference/Transform-parent.html
您的每个转塔对象仅在单个局部轴上旋转.而Unity可以处理以下问题:http://docs.unity3d.com/Documentation/ScriptReference/Transform-localRotation.html
当一个对象成为另一个对象的父对象时,可以在所需的轴上本地旋转它. Unity自行处理整个矩阵转换.修改对象的全局旋转时,基本上是覆盖来自育儿的转换.在这一点上,随时间推移,任何层次结构都很容易获得错误和不精确性.
编辑:有了你的包裹,我能够写出我的意思:
public class WeaponMover : MonoBehavIoUr
{
public GameObject boat;
public GameObject turretRotateObj;
public GameObject towerRotateObj;
public GameObject target;
private Vector3 lastDirection;
// initialization
void Start()
{
lastDirection = boat.transform.forward;
}
void Update()
{
// Find direction toward our target. Use turret as origin.
Vector3 wantedDirection = target.transform.position - turretRotateObj.transform.position;
// Rotate our last direction toward that new best direction. Change floats to make it move faster or slower.
lastDirection = Vector3.Rotatetowards(lastDirection, wantedDirection, 0.01f, 0.01f);
// Find the direction local to the tower as the boat can move around!
Vector3 towerDirection = boat.transform.InverseTransformDirection(lastDirection);
// Remove unwanted axis
towerDirection = new Vector3(-towerDirection.z, 0, towerDirection.x);
towerDirection.normalize();
// Set local rotation
towerRotateObj.transform.localRotation = Quaternion.LookRotation(towerDirection);
// Find the direction local to the gun, as the tower may have rotated!
Vector3 turretDirection = towerRotateObj.transform.InverseTransformDirection(lastDirection);
// Remove unwanted axis.
turretDirection = new Vector3(turretDirection.x, turretDirection.y, 0);
turretDirection.normalize();
// Set local rotation
turretRotateObj.transform.localRotation = Quaternion.LookRotation(turretDirection);
}
}
注意:由于我很懒,我不得不将枪管移动到Z轴而不是X轴.因此,如果仅复制粘贴此代码,则枪管将指向框架,但枪支将正确跟随目标.
由于旋转现在是本地的,因此您可以旋转船数年,并且喷枪永远不会偏移.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。