• unity2D以最小的角度旋转到目标方向(y方向为角色的主方向)


    一.使用向量原理转换到目标方向

    为了让角色的自身y转向目标方向,并且以最小角度旋转,要点是获得当前方向与目标方向的叉值,从而判断应该旋转的方向

    float rotateSpeed;

    //相对目标位置运动
    void trackPosition02(Vector3 tarPosition)
    {
    Vector3 targetDir = tarPosition - transform.position;
    Vector3 up = transform.up;
    float angle = Vector3.Angle(targetDir, up);
    if (angle <= Time.fixedDeltaTime * rotateSpeed) return;//判断角度是否小于临界值,如果小于,那么不需要旋转,此处用于避免旋转抖动
    Vector3 cross = Vector3.Cross(up, targetDir);
    if (cross.z > 0) transform.Rotate(new Vector3(0, 0, rotateSpeed0* Time.deltaTime)); else transform.Rotate(new Vector3(0, 0, -rotateSpeed0* Time.deltaTime));
    }

    可能unity提供了更简单的判定方式,知道的老兄留个评论

    二.利用角度符号判断转到目标方向

    这里原理和一相同,只是判断角度的方式是使用判断两者的角度差,而不是向量的叉值

    float angle = Vector3.SignedAngle(transform.up, target.position - transform.position, Vector3.forward);
    transform.Rotate(new Vector3(0, 0, Mathf.Sign(angle) * speed * Time.deltaTime));

    三.有角度限制的转到目标方向

    这里角度限制是指在局部坐标系内的角度限制,比如某个TD坦克,它的炮塔只能在正方向的-30度到正30度之间旋转,

    但是除了计算局部旋转,还要加上父物体的旋转角度

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class RotateTest : MonoBehaviour
    {
        // The target marker.
        public Transform target;
    
        // Angular speed in radians per sec.
        public float speed;
    
        //Vector3.up方向为0角度方向
        //局部坐标系内的最小角度和最大角度
        public float minAngle;
        public float maxAngle;
    
        //局部坐标系内的最小角度和最大角度转换到直接坐标系的值
        public float minAngleInWorld;
        public float maxAngleInWorld;
    
        void Update()
        {
            //父亲物体的当前角度
            float offsetAngle = Vector3.SignedAngle(Vector3.up, transform.parent.transform.up,Vector3.forward);
    
            minAngleInWorld = minAngle + offsetAngle;
            maxAngleInWorld = maxAngle + offsetAngle;
    
            //当前的目标方向相对世界坐标Up方向的角度,用于判断是否在设定的范围内
            float angle = Vector3.SignedAngle(Vector3.up, target.position - transform.position, Vector3.forward);
            //当前自身与目标的角度方向差,用于决定旋转方向
            float signAngle = Vector3.SignedAngle(transform.up, target.position - transform.position, Vector3.forward);
            if (angle > minAngleInWorld && angle < maxAngleInWorld) transform.Rotate(new Vector3(0, 0, Mathf.Sign(signAngle)*speed * Time.deltaTime));
            
            /*
            float angle = Vector3.SignedAngle(transform.up, target.position - transform.position, Vector3.forward);
            transform.Rotate(new Vector3(0, 0, Mathf.Sign(angle) * speed * Time.deltaTime));
            */
        }
    }

    四.利用unity的接口旋转

    //数学意义的转到目标方向
        protected void RotateToDir(Vector3 dir)
        {
            float angle = Vector3.SignedAngle(Vector3.up, dir, Vector3.forward);
            Quaternion rotation00 = Quaternion.Euler(0, 0, angle);
            transform.rotation = Quaternion.RotateTowards(transform.rotation, rotation00, Time.fixedDeltaTime * computeRotateSpeed);
        }
  • 相关阅读:
    以中间件,路由,跨进程事件的姿势使用WebSocket
    傻瓜式解读koa中间件处理模块koa-compose
    企业管理系统前后端分离架构设计 系列一 权限模型篇
    vue权限路由实现方式总结
    3YAdmin-专注通用权限控制与表单的后台管理系统模板
    lazy-mock ,一个生成后端模拟数据的懒人工具
    vue-quasar-admin 一个包含通用权限控制的后台管理系统
    CSS中line-height与vertical-align
    IdentityServer4实现Token认证登录以及权限控制
    利用AOP实现SqlSugar自动事务
  • 原文地址:https://www.cnblogs.com/xiaoahui/p/10206707.html
Copyright © 2020-2023  润新知