近战攻击的贴花方向(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,黄色的类似长方形我们假定是攻击的特效.图中的蓝色,绿色,红色线是代码里绘制的,代表了他的坐标轴.
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轴朝着碰撞墙面的法线方向,所以要把旋转Z到X , 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), "灰色长棍子是投影于平面的向量"); }}
放上几张图方便理解.
0 0
- 近战攻击的贴花方向(Quaternion)问题
- 贴花
- Unity3d调用Quaternion的函数问题
- 未来的方向问题!!!!!!
- pv3d 的 Quaternion练习
- Ogre 的 四元数quaternion
- Ogre的四元数quaternion
- Ogre的四元数quaternion
- Quaternion的研究
- Ogre 的 四元数quaternion
- Unity3D的四元数 Quaternion
- Unity3D的四元数 Quaternion
- unity3d的四元数 Quaternion
- unity3d的四元数 Quaternion
- unity3d的四元数 Quaternion
- Quaternion.Slerp的使用
- Quaternion 的探索
- unity3d的四元数 Quaternion
- 六,七单元笔记
- HTTP协议方法以及报头分析
- Tensorflow在Android上的实现(一)Build官方Demo
- Oozie作业调度
- Unicode编码及其编码方式
- 近战攻击的贴花方向(Quaternion)问题
- 即时通讯-Android推送方案(MQTT)
- android base64加密
- 用友nc65开发报错xxx is not found in jndi please deploy it!} jndiName: xxx
- Java的匿名内部类与Lambda表达式
- 我由Angular转向React,为什么
- js 的几种面向对象的方式
- 前端工程化基础
- 怎样安装 JDK8 到 Ubuntu 14.04 和 12.04