我被要求研究用Unity创建一个简单的迭代应用程序.此应用程序有两个关于相机的主要功能.
> LERP-ing相机聚焦在目标物体上.
>一旦将放弃控制移动到用户并允许用户旋转和缩放对象.
我是新手,但我已经设法创建了两个单独实现这些目标的脚本.现在我正努力让他们融合在一起.
我将从用户交互的相关代码开始.
首先,我使用TouchKit在Start中设置每个帧的delta值.
// set the delta on each frame for horizontal and vertical rotation
var oneTouch = new TKPanRecognizer();
oneTouch.gestureRecognizedEvent += (r) =>
{
HorizontalDelta += r.deltaTranslation.x * rotateSpeed * Time.deltaTime;
VerticalDelta -= r.deltaTranslation.y * rotateSpeed * Time.deltaTime;
};
// do the same for pinch
var pinch = new TKPinchRecognizer();
pinch.gestureRecognizedEvent += (r) =>
{
rotateDistance -= r.deltaScale * 200.0f * Time.deltaTime;
};
TouchKit.addGestureRecognizer(oneTouch);
TouchKit.addGestureRecognizer(pinch);
并在更新:
VerticalDelta = Mathf.Clamp(VerticalDelta, verticalPivotMin, verticalPivotMax);
var direction = GetDirection(HorizontalDelta, VerticalDelta);
var currentTarget = targetsSwitched ? target2 : target;
transform.position = currentTarget.position - direction * rotateDistance;
transform.LookAt(currentTarget.position);
// ...
private Vector3 GetDirection(float x, float y)
{
Quaternion q = Quaternion.Euler(y, x, 0);
return q * Vector3.forward;
}
这很好用,完全符合我的要求.当我尝试将此代码与我的相机移动脚本集成时,问题就来了.这显示了我想要添加更新代码的位置
void Update ()
{
if (currentlyMoving)
{
FocusTarget(currentTarget);
}
else
{
// accept user input if not moving
if (Input.GetKeyDown(KeyCode.Space))
{
SetMoveToTarget(mainTargetObject);
}
if (Input.GetKeyDown(KeyCode.Q))
{
SetMoveToTarget(subTargetObject1);
}
if (Input.GetKeyDown(KeyCode.E))
{
SetMoveToTarget(subTargetObject2);
}
}
}
这些是实际移动相机的功能:
void SetMoveToTarget(GameObject target)
{
if (currentlyMoving == false)
{
currentlyMoving = true;
fromRotation = currentTarget.transform.rotation;
currentTarget = target;
toRotation = currentTarget.transform.rotation;
timeStartedLerping = Time.time;
}
}
void FocusTarget(GameObject target)
{
float timeSinceStarted = Time.time - timeStartedLerping;
float percentageComplete = timeSinceStarted / (lerpSpeed);
transform.position = Vector3.MoveTowards(transform.position, target.transform.position, moveSpeed * Time.deltaTime);
transform.rotation = Quaternion.Lerp(fromRotation, toRotation, Mathf.Pow(percentageComplete, (float)1.2));
if (Vector3.Distance(transform.position, target.transform.position) < 0.1 && percentageComplete > 0.99)
{
transform.position = target.transform.position;
transform.rotation = target.transform.rotation;
currentlyMoving = false;
}
}
我认为我需要做的事情(我可能错了)将rotateDistance设置为第二个脚本中的currentTarget和第一个脚本中的currentTarget之间的差异.
提前谢谢你,这对我来说非常棘手.
最佳答案 最后,我不得不改变我在第一时间移动相机的方式.问题是移动到设置的游戏对象是有效的并且易于设置但是如果您实际计算相机的下一个位置应该移动到那个时间,则更容易与外观脚本集成.
我打算将这个工作产品粘贴到后代,它在最终游戏中缺少一些东西,但相机正在工作.
using UnityEngine;
using UnityEngine.UI;
public class NewCamera : MonoBehaviour {
// targets
public GameObject target;
public GameObject target2;
// settings
public float RotateSpeed = 50.0f;
public float RotateDistance = 3;
public float CameraMoveSpeed = 20f;
public float VerticalPivotMin = 5;
public float VerticalPivotMax = 65;
public float MinZoomIn = 1.7f;
public float MaxZoomIn = 4f;
// private
private GameObject lookTarget;
private bool currentlyMoving = false;
private Vector3 targetVector;
private float timeStartedLerping;
private float HorizontalDelta;
private float VerticalDelta;
void Start ()
{
lookTarget = target;
var oneTouch = new TKPanRecognizer();
oneTouch.gestureRecognizedEvent += (r) =>
{
if (currentlyMoving == false)
{
HorizontalDelta += r.deltaTranslation.x * RotateSpeed * Time.deltaTime;
VerticalDelta -= r.deltaTranslation.y * RotateSpeed * Time.deltaTime;
VerticalDelta = Mathf.Clamp(VerticalDelta, VerticalPivotMin, VerticalPivotMax);
}
};
var pinch = new TKPinchRecognizer();
pinch.gestureRecognizedEvent += (r) =>
{
if (currentlyMoving == false)
{
RotateDistance -= r.deltaScale * 200.0f * Time.deltaTime;
RotateDistance = Mathf.Clamp(RotateDistance, MinZoomIn, MaxZoomIn);
}
};
TouchKit.addGestureRecognizer(oneTouch);
TouchKit.addGestureRecognizer(pinch);
}
void Update ()
{
if (currentlyMoving)
{
FocusTarget();
}
else
{
var direction = GetDirection(HorizontalDelta, VerticalDelta);
transform.position = lookTarget.transform.position - direction * RotateDistance;
transform.LookAt(lookTarget.transform.position);
}
}
public void OnButtonClick()
{
var currentTarget = target.GetInstanceID() == lookTarget.GetInstanceID() ? target : target2;
var nextTarget = currentTarget.GetInstanceID() == target.GetInstanceID() ? target2 : target;
var cameraPosition = transform.position;
var targetPosition = currentTarget.transform.position;
SetMoveToTarget(nextTarget, cameraPosition - targetPosition);
}
void SetMoveToTarget(GameObject moveTo, Vector3 offset)
{
currentlyMoving = true;
targetVector = moveTo.transform.position + offset;
lookTarget = moveTo;
}
void FocusTarget()
{
transform.position = Vector3.Lerp(transform.position, targetVector, CameraMoveSpeed * Time.deltaTime);
if (Vector3.Distance(transform.position, targetVector) < 0.01)
{
transform.position = targetVector;
currentlyMoving = false;
}
}
private Vector3 GetDirection(float x, float y)
{
Quaternion q = Quaternion.Euler(y, x, 0);
return q * Vector3.forward;
}
}
如果您出于任何原因想要使用它,只需将此脚本添加到摄像机并设置两个目标.我必须制作一个更强大的版本,您可以轻松添加新目标,但现在这样做.
快乐的黑客!