Commom(十五)—— ShakeCamera摇晃摄像机

本文介绍了一个Unity中用于实现摄像机抖动效果的组件ShakeCamera。该组件通过设置不同的参数,如周期、偏移周期、振动时间等,可以实现水平、垂直或正朝向三种不同方向的抖动效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录为:Assets/Scripts/Common/
ShakeCamera.cs
挂到一个canmera上面就能用了
using UnityEngine;
using System.Collections;

public class ShakeCamera: MonoBehaviour
{
    public enum ShakeOrient
    {
        horizontal,     //水平
        vertical,       //垂直
        forward,        //正朝向
    }

    //周期
    public float mPeriod = 2;

    //偏移周期
    public float mOffPeriod = 0;

    public ShakeOrient mShakeOrient = ShakeOrient.horizontal;

    //振动时间
    public float mShakeTime = 10.0f;

    //最大波峰
    public float mMaxWave = 5;

    //最小波峰
    public float mMinWave = 1;

    //总共经过时间
    private float mCurTime = 0;

    //是否shake状态
    public bool mIsShake = false;

    //初始位置
    public Vector3 mDefaultPos;

    //振动方向
    public Vector3 mShakeDir;

    public Transform mCamerTrans;

    //获取Transform
    public Transform GetTransform()
    {
        if (mCamerTrans == null)
        {
            mCamerTrans = gameObject.transform;
        }

        return mCamerTrans;
    }

    //振屏
    public void ShakeScreen(ShakeOrient shakeOrient, float period, float shakeTime, float maxWave, float minWave, float offPeriod = 0)
    {
        //不在振动状态
        if (!mIsShake)
        {
            //确保Transform有效
            if (GetTransform() == null)
            {
                return;
            }

            mShakeOrient = shakeOrient;
            mPeriod = period;
            mShakeTime = shakeTime;
            mMaxWave = maxWave;
            mMinWave = minWave;
            mOffPeriod = offPeriod;

            //保存默认位置
            mDefaultPos = transform.localPosition;

            //垂直方向
            if (shakeOrient == ShakeOrient.vertical)
            {
                mShakeDir = new Vector3 (0, 1, 0);
            }
            else if (shakeOrient == ShakeOrient.forward)
            {
                mShakeDir = mCamerTrans.forward;
            }
            else if (shakeOrient == ShakeOrient.horizontal)
            {
                Vector3 v1 = new Vector3 (0, 1, 0);
                Vector3 v2 = mCamerTrans.forward;

                //叉乘,得到同时垂直于v1,v2的向量
                mShakeDir = Vector3.Cross (v1, v2);
                mShakeDir.Normalize ();
            }

            mIsShake = true;
        }
    }

    public void Update()
    {
        if (mIsShake)
        {
            //已用过的时间/总的shake时间
            float factor = mCurTime / mShakeTime;

            //总周期
            //2PI
            float totalPeriod = mPeriod * Mathf.PI;

            //当前时刻值
            float maxValue = mMaxWave - (mMaxWave - mMinWave) * factor;

            //当前弧度值
            //mOffPeriod为0时,
            //radValue就是根据时间来算角度,,,时间流逝,rad增大
            float radValue = mOffPeriod * Mathf.PI + factor * totalPeriod;

            //这样子的感觉: value = ASin(rad)
            //A不断减小,rad从0到2PI不断增大
            //按正弦函数,振幅不断减小,最后减小为0
            float value = maxValue * Mathf.Sin (radValue);

            //垂直振动,只固定y方向
            if (mShakeOrient == ShakeOrient.vertical)
            {
                transform.localPosition =
                    new Vector3 (transform.localPosition.x, mDefaultPos.y, transform.localPosition.z)
                + mShakeDir * value;
            }
            else
            {
                transform.localPosition = mDefaultPos + mShakeDir * value;
            }

            mCurTime += Time.deltaTime;

            //结束振屏状态上
            if (mCurTime > mShakeTime)
            {
                mIsShake = false;
                mCurTime = 0;
            }

        }
    }


    void OnGUI()
    {
        if (GUI.Button(new Rect(10, 10, 150, 100), "Shake!"))
        {
            ShakeScreen (mShakeOrient, mPeriod, mShakeTime, mMaxWave, mMinWave, mOffPeriod);

            mIsShake = true;
            //保存默认位置
            mDefaultPos = transform.localPosition;
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值