unity3d - 移动设备上的 Unity2D 对象旋转
问题描述
我想知道是否只有当用户单击并拖动游戏对象时才能旋转对象。如果用户在其他任何地方单击并拖动,则游戏对象不应旋转。无论用户单击何处,带有此脚本的对象都会旋转。
void Update()
{
if (Input.touchCount > 0)
{
touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Moved)
{
Vector2 dir = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position) - Camera.main.ScreenToWorldPoint(transform.position);
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
Quaternion rotation = Quaternion.AngleAxis(angle - 90, Vector3.forward);
transform.rotation = rotation;
transform.rotation = rotationZ * transform.rotation;
}
}
解决方案
您当前的代码确实只检查触摸..这些是否“击中”任何东西都没有关系。
例如,您可以使用 aPhysics.Raycast
来检查您的触摸是否在使用的对象上方
// store the direction from object to touch when the touch started
private Vector2 startDirection;
// store the objects orientation when the touch started
private Quaternion startRotation;
// only process touch moved if the touch actually started above this object
private bool isValidTouch;
// The collider of this object
[SerializeField] Collider _collider;
// The main camera
[SerializeField] Camera _mainCamera;
private void Awake()
{
if(!_collider) _collider = GetComponent<Collider>();
if(!_mainCamera) _mainCamera = Camera.main;
}
void Update()
{
if (Input.touchCount > 0)
{
touch = Input.GetTouch(0);
var touchPosition = touch.position;
switch(touch.phase)
{
case TouchPhase.Began:
// Check if this touch actually is over this object
if(_collider.RayCast(_mainCamera.ScreenPointToRay(touchPosition), out var hit))
{
// Now store initial data
// You want to do ONLY ONE:
// - Either transform the touch into worldspace (more complicated)
// - OR transform the position into screenspace (easier)
// You definitely do not want to do both!
startDirection = (touchPosition - (Vector2)_mainCamera.WorldToScreenPoint(transform.position));
startRotation = transform.rotation;
isValidTouch = true;
}
break;
case TouchPhase.Moved
if(isValidTouch)
{
// Get the current touch direction
var direction = (touchPosition - (Vector2)_mainCamera.WorldToScreenPoint(transform.position));
// Get the angle between them
var differenceAngle = Vector3.SignedAngle(startDirection, direction, Vector3.forward);
// rotate the original rotation according to the current angle
Quaternion rotation = startRotation * Quaternion.AngleAxis(differenceAngle, Vector3.forward);
transform.rotation = rotation;
}
break;
case TouchPhase.Ended
isValidTouch = false;
break;
}
}
}
推荐阅读
- javascript - Observable.subscribe() 在 IE 中无法在 Angular 7 中更改组件
- php - 如何强制子类实现其父类接口方法
- unity3d - LeanTween 由于时间尺度 0 而没有做任何事情。解决方法是什么?
- c# - C# 在 for 中使用字符串
- php - 在 Lumen Laravel '未定义变量:状态'中运行测试时出现 PHPUnitTest 错误
- sql - Oracle SQL 将十六进制值选择为 SHA256
- c# - Xamarin Forms ListView ItemTapped 到来自 ViewModel 的对象
- javascript - 模拟/测试 Vuex 存储模块给了我 TypeError 问题
- javascript - 在asp页面上使用javascript移动浏览器窗口
- docker - 无法在容器内进行 apt update