使用视差和Movetoward,将相机移动到正确的方向的问题
我有一台电影摄像头,需要使用新的输入系统跟随播放器左右滑动。在我的CM摄像机上,我附加了以下组件:
- 一个称为摄像机滑动
- 播放器输入组件的脚本,该脚本将其映射到默认地图,称为“ Swipe Map”,在屏幕控制资产中,
- 一个名为屏幕屏幕管理器
屏幕输入管理器代码在下面:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
[DefaultExecutionOrder(-1)]
public class ScreenInputManager : MonoBehaviourSingleton<ScreenInputManager>
{
public GameObject player;
#region
public delegate void StartTouch(Vector2 position, float time);
public event StartTouch OnStartTouch;
public delegate void EndTouch(Vector2 position, float time);
public event StartTouch OnEndTouch;
#endregion
private ScreenControls screenControls;
private Camera mainCamera;
private void Awake()
{
screenControls = new ScreenControls(); // new instance of input manager
screenControls.SwipeMap.Enable();
screenControls.Enable();
mainCamera = Camera.main;
}
private void OnEnable()
{
screenControls.Enable();
}
private void OnDisable()
{
screenControls.Disable();
}
private void Start()
{
screenControls.SwipeMap.PrimaryContact.started += context => StartTouchPrimary(context);
screenControls.SwipeMap.PrimaryContact.canceled += context => EndTouchPrimary(context);
}
private void StartTouchPrimary(InputAction.CallbackContext context)
{
if (OnStartTouch != null) OnStartTouch(Utils.ScreenToWorld(mainCamera, screenControls.SwipeMap.PrimaryPosition.ReadValue<Vector2>()), (float)context.startTime); // avoid using screen to world here, do it later
}
private void EndTouchPrimary(InputAction.CallbackContext context)
{
if (OnEndTouch != null) OnEndTouch(Utils.ScreenToWorld(mainCamera, screenControls.SwipeMap.PrimaryPosition.ReadValue<Vector2>()), (float)context.time); // avoid using screen to world here, do it later
}
public Vector2 PrimaryPosition()
{
return screenControls.SwipeMap.PrimaryPosition.ReadValue<Vector2>();
}
}
摄像机滑动代码如下:
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
[DefaultExecutionOrder(-1)]
public class CameraSwipe : MonoBehaviour
{
[SerializeField] private float minimumDistance = 1f;
[SerializeField] private float maximumTime = 1f;
[SerializeField, Range(0f, 1f)] private float directionThreshhold = 0.9f;
// private ScreenInputManager inputSystem;
private Vector2 startPosition;
private float startTime;
private Vector2 endPosition;
private float endTime;
private Vector3 targetPosition;
private ScreenInputManager inputProvider;
private CinemachineVirtualCamera virtualCamera;
private Rigidbody2D cameraRigid;
private Transform cameraTransform;
private void Awake()
{
inputProvider = GetComponent<ScreenInputManager>();
virtualCamera = GetComponent<CinemachineVirtualCamera>();
cameraRigid = GetComponent<Rigidbody2D>();
cameraTransform = virtualCamera.VirtualCameraGameObject.transform;
}
private void OnEnable()
{
inputProvider.OnStartTouch += SwipeStart;
inputProvider.OnEndTouch += SwipeEnd;
}
private void OnDisable()
{
inputProvider.OnStartTouch -= SwipeStart;
inputProvider.OnEndTouch -= SwipeEnd;
}
private void SwipeStart(Vector2 position, float time)
{
startPosition = position;
startTime = time;
}
private void SwipeEnd(Vector2 position, float time)
{
endPosition = position;
endTime = time;
}
private void Update()
{
if (Vector3.Distance(startPosition, endPosition) >= minimumDistance && (endTime - startTime) <= maximumTime)
{
Debug.DrawLine(startPosition, endPosition, Color.red, 5f);
Vector3 direction = endPosition - startPosition; // halfway between start and end?
targetPosition = cameraTransform.position;
targetPosition.x = -direction.x;
Vector2 direction2D = new Vector2(direction.x, direction.y).normalized;
SwipeDirection(targetPosition, direction2D);
}
}
private void SwipeDirection(Vector3 direction, Vector2 direction2D)
{
if (Vector2.Dot(Vector2.left, direction) > directionThreshhold)
{
Debug.Log("left " + " the direction 2d is: " + direction2D);
cameraTransform.position = Vector3.MoveTowards(cameraTransform.position, direction, Time.deltaTime * (float) 3);
}
else if (Vector2.Dot(Vector2.right, direction) > directionThreshhold)
{
Debug.Log("right " + " the direction 2d is: " + direction2D);
cameraTransform.position = Vector3.MoveTowards(cameraTransform.position, direction, Time.deltaTime * (float) 3);
}
}
}
问题 - 问题是,当我向右滑动时,它似乎会发现左滑动屏幕。似乎并没有轻易从右铲中挑选。
我尝试过的内容: - 我认为这可能与在update()中调用SwipDirection有关,而实际上应该在Swipeend()末尾称呼它。但是当我这样做时,因为它没有不断更新,所以相机只会移动一点,根本就不会流畅。
我还试图做一堆debug.logs。当变量方向2D(在第二个代码块中)等于“ 0”时,似乎会失速。有人可以帮我解决这个问题吗?
I have a Cinemachine camera that needs to follow the player swiping left and right using the new input system. To my CM camera, I have attached the following components:
- A script called Camera Swipe
- A player input component, which maps to a default map called Swipe Map, in a Screen Controls asset
- A script called Screen Input Manager
The screen input manager code is below:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
[DefaultExecutionOrder(-1)]
public class ScreenInputManager : MonoBehaviourSingleton<ScreenInputManager>
{
public GameObject player;
#region
public delegate void StartTouch(Vector2 position, float time);
public event StartTouch OnStartTouch;
public delegate void EndTouch(Vector2 position, float time);
public event StartTouch OnEndTouch;
#endregion
private ScreenControls screenControls;
private Camera mainCamera;
private void Awake()
{
screenControls = new ScreenControls(); // new instance of input manager
screenControls.SwipeMap.Enable();
screenControls.Enable();
mainCamera = Camera.main;
}
private void OnEnable()
{
screenControls.Enable();
}
private void OnDisable()
{
screenControls.Disable();
}
private void Start()
{
screenControls.SwipeMap.PrimaryContact.started += context => StartTouchPrimary(context);
screenControls.SwipeMap.PrimaryContact.canceled += context => EndTouchPrimary(context);
}
private void StartTouchPrimary(InputAction.CallbackContext context)
{
if (OnStartTouch != null) OnStartTouch(Utils.ScreenToWorld(mainCamera, screenControls.SwipeMap.PrimaryPosition.ReadValue<Vector2>()), (float)context.startTime); // avoid using screen to world here, do it later
}
private void EndTouchPrimary(InputAction.CallbackContext context)
{
if (OnEndTouch != null) OnEndTouch(Utils.ScreenToWorld(mainCamera, screenControls.SwipeMap.PrimaryPosition.ReadValue<Vector2>()), (float)context.time); // avoid using screen to world here, do it later
}
public Vector2 PrimaryPosition()
{
return screenControls.SwipeMap.PrimaryPosition.ReadValue<Vector2>();
}
}
The Camera Swipe code is below:
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
[DefaultExecutionOrder(-1)]
public class CameraSwipe : MonoBehaviour
{
[SerializeField] private float minimumDistance = 1f;
[SerializeField] private float maximumTime = 1f;
[SerializeField, Range(0f, 1f)] private float directionThreshhold = 0.9f;
// private ScreenInputManager inputSystem;
private Vector2 startPosition;
private float startTime;
private Vector2 endPosition;
private float endTime;
private Vector3 targetPosition;
private ScreenInputManager inputProvider;
private CinemachineVirtualCamera virtualCamera;
private Rigidbody2D cameraRigid;
private Transform cameraTransform;
private void Awake()
{
inputProvider = GetComponent<ScreenInputManager>();
virtualCamera = GetComponent<CinemachineVirtualCamera>();
cameraRigid = GetComponent<Rigidbody2D>();
cameraTransform = virtualCamera.VirtualCameraGameObject.transform;
}
private void OnEnable()
{
inputProvider.OnStartTouch += SwipeStart;
inputProvider.OnEndTouch += SwipeEnd;
}
private void OnDisable()
{
inputProvider.OnStartTouch -= SwipeStart;
inputProvider.OnEndTouch -= SwipeEnd;
}
private void SwipeStart(Vector2 position, float time)
{
startPosition = position;
startTime = time;
}
private void SwipeEnd(Vector2 position, float time)
{
endPosition = position;
endTime = time;
}
private void Update()
{
if (Vector3.Distance(startPosition, endPosition) >= minimumDistance && (endTime - startTime) <= maximumTime)
{
Debug.DrawLine(startPosition, endPosition, Color.red, 5f);
Vector3 direction = endPosition - startPosition; // halfway between start and end?
targetPosition = cameraTransform.position;
targetPosition.x = -direction.x;
Vector2 direction2D = new Vector2(direction.x, direction.y).normalized;
SwipeDirection(targetPosition, direction2D);
}
}
private void SwipeDirection(Vector3 direction, Vector2 direction2D)
{
if (Vector2.Dot(Vector2.left, direction) > directionThreshhold)
{
Debug.Log("left " + " the direction 2d is: " + direction2D);
cameraTransform.position = Vector3.MoveTowards(cameraTransform.position, direction, Time.deltaTime * (float) 3);
}
else if (Vector2.Dot(Vector2.right, direction) > directionThreshhold)
{
Debug.Log("right " + " the direction 2d is: " + direction2D);
cameraTransform.position = Vector3.MoveTowards(cameraTransform.position, direction, Time.deltaTime * (float) 3);
}
}
}
The problem - The issue is that it seems to detect a left swipe sometimes when I'm swiping right, and sometimes it seems to stall and not go past certain parts of the screen. It seems to not be picking apart left swipes from right ones easily.
What I've tried: - I think it might be to do with calling SwipeDirection in Update(), when it really should just be called at the end of SwipeEnd(). But when I do that, then because it's not continually updated, the camera only moves a tiny bit and not fluidly at all.
I've also tried to do a bunch of Debug.Logs. It seems to stall when the variable Direction2D (in the second code block) is equal to "0". Can someone help me fix this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论