近战攻击的贴花方向(Quaternion)问题

来源:互联网 发布:windows thin pc 编辑:程序博客网 时间:2024/04/29 16:58

2近战攻击,加入拿的看到,砍在墙上地上要有痕迹的粒子效果.

关于贴花需要做到位置和旋转的改变.

1,位置位于碰撞到的位置.
2,旋转应该是位于碰撞点的法线.
3,碰撞点的法线只是向上的,并没有旋转,那么我们希望它能够面朝玩家.

我做了下面的测试效果.

using UnityEngine;using System.Collections;public class CTestNormal : MonoBehaviour{    public Transform pic;    public Transform pic2;    float t = 0f;    void Update()    {        //if (Time.time < t)          //  return;        //t = Time.time + 1f;        Vector3 at = transform.position;        RaycastHit targetHit;        bool raytrigger = Physics.Raycast(at, transform.forward, out targetHit);        if (!raytrigger)            return;        float dis = Vector3.Distance(targetHit.point, transform.position);        Debug.DrawRay(at, transform.forward * dis, Color.blue);        Debug.DrawRay(pic.position + pic.forward * 0.05f, pic.forward, Color.blue); // 绘制每根轴        Debug.DrawRay(pic.position + pic.forward * 0.05f, pic.right, Color.red);        Debug.DrawRay(pic.position + pic.forward * 0.05f, pic.up, Color.green);        Quaternion normal = Quaternion.LookRotation( targetHit.normal); //打到墙上的射线旋转        //计算贴花在墙面的投影向量        Vector3 rot = Vector3.Cross(targetHit.normal, -transform.forward);   //算垂直于墙面法线和攻击方向的向量        //Vector3 touyingV3 = Vector3.Cross(targetHit.normal, rot); // 向量的投影        touying.transform.forward = touyingV3;        Quaternion rot2 = Quaternion.LookRotation(touyingV3);   //转为角度        Vector3 er = Vector3.zero;        er.z = rot2.eulerAngles.x +90f;   //对于rot2的x轴的旋转正好是看向发射点的z轴旋转 + 90f , 转到贴花的方向.        normal.eulerAngles  += er;        pic.eulerAngles = normal;        pic.transform.position = targetHit.point;        pic2.eulerAngles = rot.eulerAngles;        pic2.transform.position = targetHit.point;    }}

图1
如图1: 红色是地面,蓝色是墙.
1,黄色的类似长方形我们假定是攻击的特效.图中的蓝色,绿色,红色线是代码里绘制的,代表了他的坐标轴.
2,黄绿色的一个永远面向胶囊的,是一个对比看效果,Scene中的箭头是我选中的黄绿色的transform显示出来的.

实现方法就是先计算法线旋转,然后再把朝向玩家的旋转附加给他,就简单实现了.

图2:地面效果
这里写图片描述


————————————————————————-华丽的分割线——————————————————-


上面的例子经过测试有很多不足,如果在斜方向砍墙, 贴花的角度就有问题了,下面进行了优化.

using UnityEngine;using System.Collections;public class CTestNormal : MonoBehaviour{    public Transform flower;    public Transform pic2;    public Transform phyDir;    public Transform phyDirChuizhi;    public Transform touying;    float t = 0f;    void Update()    {        //if (Time.time < t)          //  return;        //t = Time.time + 1f;        Vector3 at = transform.position;        RaycastHit targetHit;        bool raytrigger = Physics.Raycast(at, transform.forward, out targetHit);        if (!raytrigger)            return;        float dis = Vector3.Distance(targetHit.point, transform.position);        Debug.DrawRay(at, transform.forward * dis, Color.blue);        Debug.DrawRay(flower.position + flower.forward * 0.05f, flower.forward, Color.blue); // 绘制每根轴        Debug.DrawRay(flower.position + flower.forward * 0.05f, flower.right, Color.red);        Debug.DrawRay(flower.position + flower.forward * 0.05f, flower.up, Color.green);        Quaternion normal = Quaternion.LookRotation( targetHit.normal); //打到墙上的射线旋转        Vector3 myforward = transform.forward; //镜头的方向,这里的贴花是根据第一人称武器挥舞作为参考方向的.        //计算投影向量        Vector3 rot = Vector3.Cross(myforward, phyDir.forward);   //算垂直于镜头法线和攻击方向的向量        phyDirChuizhi.transform.forward = rot;  //测试用来显示的        Vector3 touyingV3 = Vector3.Cross(targetHit.normal, rot); // 向量phyDir到墙面的投影        touying.transform.position = targetHit.point;   //测试用来显示的        touying.transform.forward = touyingV3;        Quaternion rot2 = Quaternion.LookRotation(touyingV3, targetHit.normal);   //得到一个墙面法线向上的投影方向的向量        //因为这个物理攻击贴花是Z轴朝着碰撞墙面的法线方向,所以要把旋转ZX , Z再旋转到Y才可以.        Quaternion dirq = Quaternion.FromToRotation(Vector3.forward, Vector3.right);            Quaternion dirq2 = Quaternion.FromToRotation(Vector3.forward, Vector3.up);        flower.transform.rotation = rot2 * dirq * dirq2; //最终的方向.        flower.transform.position = targetHit.point;        pic2.eulerAngles = rot2.eulerAngles;        pic2.transform.position = targetHit.point;    }    void OnGUI()    {        GUI.color = Color.black;        Vector3 pt;        pt = Camera.main.WorldToScreenPoint(flower.transform.position);        GUI.Label(new Rect(pt.x, pt.y, 200, 50), "武器砍出来的贴花(最终效果)");        pt = Camera.main.WorldToScreenPoint(phyDir.transform.position);        GUI.Label(new Rect(pt.x, pt.y, 200, 50), "武器砍出来物理方向");        pt = Camera.main.WorldToScreenPoint(phyDirChuizhi.transform.position);        GUI.Label(new Rect(pt.x, pt.y, 200, 50), "垂直于物理方向的方向,用来计算投影向量");        pt = Camera.main.WorldToScreenPoint(touying.transform.position+new Vector3(0f,0.2f,0f));        GUI.Label(new Rect(pt.x, pt.y, 200, 50), "灰色长棍子是投影于平面的向量");    }}

放上几张图方便理解.
这个是Scene里的图,胶囊是玩家,大方盒子是墙,红色是地面,相机面前的白条子是武器挥舞后的力方向

这里写图片描述
这里写图片描述
这里写图片描述

0 0
原创粉丝点击