参考Unity粒子系统的StretchedBillboard,在保持模型的右朝向不变的情况下,尽量朝向摄像机
转化为数学问题: 一个向量在一个面上的投影
基础的Billboard的方向应为: 从中点指向摄像机
限制的平面为以right为法向量的平面
算法
Vector3 rightward = transform.parent.forward;
if (isShowLeft) rightward = -rightward;
Vector3 forward = (Camera.current.transform.position - transform.position).normalized;
if (isShowBack) forward = -forward;

float cosVal = Vector3.Dot(rightward, forward);
if (Mathf.Abs(cosVal) >= 0.999999f) return;

rightward = rightward * cosVal;
forward = forward - rightward;

//不能用forward改变,不能保证right朝向 有时候会反过来
if (cosVal > 0)
transform.rotation = Quaternion.LookRotation(forward, Vector3.Cross(rightward, forward));
else
transform.rotation = Quaternion.LookRotation(forward, Vector3.Cross(forward, rightward));

//角度旋转
if (billboardAngle != 0)
{
Vector3 oriAngle = transform.eulerAngles;
oriAngle.x += billboardAngle;
transform.eulerAngles = oriAngle;
}

x
24
 
1
            Vector3 rightward = transform.parent.forward;
2
            if (isShowLeft) rightward = -rightward;
3
            Vector3 forward = (Camera.current.transform.position - transform.position).normalized;
4
            if (isShowBack) forward = -forward;
5

6
            float cosVal = Vector3.Dot(rightward, forward);
7
            if (Mathf.Abs(cosVal) >= 0.999999f) return;
8

9
            rightward = rightward * cosVal;
10
            forward = forward - rightward;
11

12
            //不能用forward改变,不能保证right朝向 有时候会反过来
13
            if (cosVal > 0)
14
                transform.rotation = Quaternion.LookRotation(forward, Vector3.Cross(rightward, forward));
15
            else
16
                transform.rotation = Quaternion.LookRotation(forward, Vector3.Cross(forward, rightward));
17

18
            //角度旋转
19
            if (billboardAngle != 0)
20
            {
21
                Vector3 oriAngle = transform.eulerAngles;
22
                oriAngle.x += billboardAngle;
23
                transform.eulerAngles = oriAngle;
24
            }
效果: 白色为粒子系统的StretchedBillboard 红色为仿制的StretchedBillboard
 
最终计算朝向






StretchedBillboard 实现的更多相关文章

随机推荐

  1. 2016 ACM/ICPC 区域赛(北京) E 题 bfs

    https://vjudge.net/problem/UVALive-7672 题意    输入一个五位数n 问由12345变到n的操作最少次数 不可达输出-1 有三种操作 1.交换相邻的位置 次数不 ...

  2. CodeForces 570D 【dfs序】

    题意: 给一颗树,根节点深度为1,每一个节点都代表一个子母. 数据输入: 节点数 询问数 从编号为2的节点开始依次输入其父节点的编号(共有节点数减1个数字输入) 字符串有节点数个小写字母 接下来询问 ...

  3. 从头开始学Android之(二)—— Android版本

    前面大致的介绍了一下Android的Linux内核层,知道Android是Google在Linux基础上创建的一个应用于移动设备的系统,并在针对移动设备的特殊性,在Linux上做了一些相应的改动建立起 ...

  4. 蓦然回首,Java 已经 24 岁了!

    01.蓦然 真没想到,Java 竟然 24 岁了(算是 90 后)! 提起 Java,印象最深刻的当然就是: class Cmower {  public static void main(Strin ...

  5. TeamCity - Docker创建

    // 创建Server docker run -it --name teamcity-server-instance \-v /home/tc_datadir:/data/teamcity_serve ...

  6. c++多线程编程:常见面试题

    题目:子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码 子线程与主线程必有一个满足条件(flag == ...

  7. [scrapy]实例:爬取jobbole页面

    工程概览: 创建工程 scrapy startproject ArticleSpider 创建spider cd /ArticleSpider/spiders/ 新建jobbole.py # -*- ...

  8. curl -s 不输出统计信息

    curl -s 不输出统计信息 学习了:https://blog.csdn.net/qinyushuang/article/details/44114583

  9. VC++ 2010编译错误 fatal error C1189 error This file requires _WIN32_WINNT to be #defined at least

    打开你的C++工程,找到里面的stdafx.h文件,然后把下面的红色内容替换成绿色的 参考:http://blog.csdn.net/dongliqiang2006/article/details/5 ...

  10. Linux-github 搭建静态博客

    1.在Github上创建一个新的Repository 到你的github上 https://github.com去create a new repository命名为 github.myblog 2. ...