我目前有一个脚本,它使GameObject相对于另一个GameObject移动,如下面的.gif所示。
我还没想到的是如何相对于另一个GameObject的位置制作相同的GameObject rotate ,使其始终以原始旋转结束,如图所示在下图中:
所以,现在我已经"动态运动" (如.gif中所示),如何创建"动态旋转" (如图中所示)?
我没有完成此类任务的经验,搜索Web也没有帮助,所以我非常感谢准备部署的脚本。谢谢你的回答。
答案 0 :(得分:1)
如果我理解正确的话,你只是想确保物体在飞行中在空中飞行时间翻转。你可以使用这样的东西:
using UnityEngine;
using System.Collections;
public class RotaionManager : MonoBehaviour {
// Motion start point
public Transform origin;
// Motion end point
public Transform destination;
// Start and en anle - 360 for single full rotation
public float startAngle = 0;
public float endAngle = 360;
void Update () {
// Distance to origin
var dstOrigin = Vector3.Distance(origin.position, transform.position);
// Distance to destination
var dstDestination = Vector3.Distance(destination.position, transform.position);
// Parameter
float t = (dstDestination + dstOrigin == 0 ? 0 : (dstOrigin / (dstDestination + dstOrigin) ) );
// The angle at current t
float angle = Mathf.Lerp(startAngle, endAngle, t);
// Rotate the object by the angle, then make sure it also faces destination
transform.rotation = Quaternion.LookRotation(destination.position - origin.position) * Quaternion.Euler(angle, 0, 0);
}
}
基于到起点和终点的距离,简单地线性插补旋转角度。您可以控制对象按开始和结束角度旋转的次数。使用旋转是为了除了围绕自己的轴旋转外,对象还将面向目标的大致方向。
看看示例项目: https://www.dropbox.com/s/g00srsjlqjx1jcz/RotationProj.zip?dl=0
修改强>
最好使用源 - 目标矢量上的物体投影距离而不是原始距离,它在陡峭的路径上看起来更好。更新功能如下所示:
void Update () {
// Projection of object on line between origin and destination
var projection = Vector3.Project(transform.position - origin.position, origin.position - destination.position) + origin.position;
// Distance to origin
var dstOrigin = Vector3.Distance(origin.position, projection);
// Distance to destination
var dstDestination = Vector3.Distance(destination.position, projection);
// Parameter
float t = (dstDestination + dstOrigin == 0 ? 0 : (dstOrigin / (dstDestination + dstOrigin) ) );
// The angle at current t
float angle = Mathf.Lerp(startAngle, endAngle, t);
// Rotate the object by the angle, then make sure it also faces destination
transform.rotation = Quaternion.LookRotation(destination.position - origin.position) * Quaternion.Euler(angle, 0, 0);
}
我还更新了示例项目
修改强>
另一种可能看起来更好的方法可能是忽略起点和终点的 Y 坐标,并进行投影。在一些极端情况下看起来好一点。代码看起来会这样:
void Update () {
Vector3 op = origin.position; op.y = 0;
Vector3 dp = destination.position; dp.y = 0;
// Projection of object on line between origin and destination
var projection = Vector3.Project(transform.position - origin.position, op - dp) + op;
// Distance to origin
var dstOrigin = Vector3.Distance(op, projection);
// Distance to destination
var dstDestination = Vector3.Distance(dp, projection);
// Parameter
float t = (dstDestination + dstOrigin == 0 ? 0 : (dstOrigin / (dstDestination + dstOrigin) ) );
// The angle at current t
float angle = Mathf.Lerp(startAngle, endAngle, t);
// Rotate the object by the angle, then make sure it also faces destination
transform.rotation = Quaternion.LookRotation(dp - op) * Quaternion.Euler(angle, 0, 0);
}
答案 1 :(得分:0)
在类似情况下帮助我的一种可能性是transform.LookAt
功能。这使您可以始终面对目标。您可以在transform.LookAt(target.transform)
方法中添加Update
之类的内容,并始终面向目标。一旦达到目标,您可能希望将其设置为常数值,因为如果您与目标位置不完全相同,可能会出现奇怪旋转的问题。
答案 2 :(得分:0)
我假设你的游戏中有一个投掷者,摇滚和目标。运动员 将岩石扔向目标,岩石应该旋转360度。
private float mag = 0 ;//will be total distance
private Vector3 throwerPos ;
private Boolean isThrown = false;// you have to set this true whenever you throw a rock.
void Update()
{
.
.
if(isThrown)
{
mag = (target.position -thrower.position).magnitude;//get distance whenever you throw it.
throwerPos = thrower.position;
rotateIt();
}
}
void rotateIt()
{
float currMag = (rock.position - throwerPos).magnitute ;//get current distance between rock and thrower and rotate it depends on distance at the throwing time
angle= Mathf.MoveTowards(0,360,currMag / mag);
rock.getComponent<Transform>().eulerAngles = new Vector3(
rock.getComponent<Transform>().eulerAngles.x,
rock.getComponent<Transform>().eulerAngles.y,
angle);
if(angle == 360)
{
rock.getComponent<Transform>().eulerAngles.z=0;
isThrown = false;
}
}
我没有执行此代码,这可能无效。这只是一个想法。我认为有很多方法可以达到这个目的。