gpt4 book ai didi

c# - 将相机平移与 Unity 中的触摸控件相结合

转载 作者:行者123 更新时间:2023-11-30 12:23:28 26 4
gpt4 key购买 nike

有人要求我研究使用 Unity 创建一个简单的迭代应用程序。此应用程序有 2 个关于相机的主要功能。

  1. LERP-ing 相机以聚焦在目标物体上。
  2. 移动后将控制权交给用户并允许用户围绕对象旋转和缩放。

我是新手,但我已经设法创建了两个独立实现这些目标的脚本。现在我正在努力将它们组合在一起。

我将从用户交互的相关代码开始。

首先,我使用 TouchKit 在 Start 中的每一帧上设置增量值。

// 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;
}

这很好用,完全符合我的要求。当我尝试将此代码与我的相机移动脚本集成时,问题就来了。这显示了我要添加 Update 代码的位置

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 设置为第二个脚本中的 currentTargetcurrentTarget 在第一个脚本中。

提前谢谢你,这对我来说是一个相当棘手的问题。

最佳答案

最后,我不得不首先改变我处理移动相机的方式。问题是移动到一个设定的游戏对象是可行的并且易于设置,但如果您实际计算出相机的下一个位置应该在什么时候并移动到那个位置,则与外观脚本集成会容易得多。

我要把工作产品贴在这里供后代使用,它缺少游戏结束时的一些内容,但相机可以正常工作。

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;
}
}

如果您出于任何原因想要使用它,只需将此脚本添加到相机并设置两个目标即可。我必须制作一个更强大的版本,您可以在其中轻松添加新目标,但现在就可以了。

祝你黑客愉快!

关于c# - 将相机平移与 Unity 中的触摸控件相结合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36500386/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com