03、事件响应函数(一)

一、激活销毁

    void OnEnable()//每次激活脚本时调用
    {
        print("OnEnable");
    }
    void OnDisable()//脚本取消激活状态调用
    {
        print("OnDisable");
    }
    void OnDestroy()//被销毁时调用
    {
        print("OnDestroy");
    }

二、鼠标事件

    /// <summary>
    /// 代码添加到需要变颜色的物体上
    /// </summary>
    void OnMouseEnter()//鼠标进入游戏对象时 执行
    {
        GetComponent<Renderer>().material.color = Color.red;
    }
    void OnMouseExit()//鼠标离开时
    {
        GetComponent<Renderer>().material.color = Color.blue;
    }
    void OnMouseDown()//鼠标点击
    {
        GetComponent<Renderer>().material.color = Color.yellow;
    }
    void OnMouseUp()//鼠标抬起
    {
        GetComponent<Renderer>().material.color = Color.green;
    }
    void OnMouseDrag()//鼠标拖拽
    {
        GetComponent<Renderer>().material.color = Color.black;
    }
    //void OnMouseOver()//持续停留在游戏对象上
    //{
    //    GetComponent<Renderer>().material.color = Color.gray;
    //}
    //void OnMouseUpAsButton()//当鼠标在同一个GUIElement或Collider按下,在释放时调用
    //{
    //    GetComponent<Renderer>().material.color = Color.yellow;
    //}

 三、触发事件

 触发信息检测(需要勾选Is Trigger)
(1)void OnTriggerEnter(Collider other) 当进入触发器
(2)void OnTriggerExit(Collider other) 当退出触发器
(3)void OnTriggerStay(Collider other) 当逗留触发器

例1:

void OnTriggerEnter(Collider other)
    {
        Destroy(gameObject);//销毁物体本身
        Destroy(other.gameObject);//销毁被碰撞的物体
    }

 

例2:

void OnTriggerEnter(Collider other)
    {
    //当进入触发器的时候,打开isKinematic使物体停止运动。重新定位物体的位置。再把isKinematic关闭,使物体自动下落
        transform.GetComponent<Rigidbody>().isKinematic = true;//打开isKinematic
        transform.position = new Vector3(0, 3, 0);
        transform.GetComponent<Rigidbody>().isKinematic = false;
    } 

四、碰撞器

碰撞信息检测
(1)void OnCollisionEnter(Collision other) 当进入碰撞器
(2)void OnCollisionExit(Collision other)
(3)void OnCollisionStay(Collision other)

例1:

void OnCollisionEnter(Collision other)
    {
        Destroy(gameObject);//销毁物体本身
        Destroy(other.gameObject);//销毁被碰撞的物体(CollisionInfo)
    }

 

例2:

void OnCollisionStay(Collision other)
    {
        //当这两个游戏对象名字相同时
        if (string.Equals("Cube",other.gameObject.name))
        {
            print("产生火花。。");
        }
    } 

 五、其他事件函数

1、OnControllerColliderHit

  在移动的时,当controller碰撞到collider时OnControllerColliderHit被调用。

    /// <summary>
    /// 这个方法用来推开角色控制器碰到的所有刚体
    /// </summary>
    public float pushPower = 2.0F;
    void OnControllerColliderHit(ControllerColliderHit hit)
    {
        Rigidbody body = hit.collider.attachedRigidbody;
        //没有刚体,返回0
        if (body == null || body.isKinematic)
            return;
        //我们不想推动在我们下边的物体。。moveDirection(当碰撞发生时,角色控制器的方向)
        if (hit.moveDirection.y < -0.3F)
            return;
        //根据移动方向计算推的方向
        //我们只把物体推向一旁,而不是往上或往下
        Vector3 pushDir = new Vector3(hit.moveDirection.x, 0, hit.moveDirection.z);
        //速度=推动方向*推动速度
        body.velocity = pushDir * pushPower;
    }

 

 2、OnJointBreak

  当附在同一对象上的关节被断开时调用。

    /// <summary>
    /// 当一个力大于这个关节的承受力时,关节将被断开。此时OnJointBreak将被调用
    /// 应用到关节的力传入到breakForce
    /// </summary>
    /// <param name="breakForce"></param>
    void OnJoinBreak(float breakForce)
    {
        Debug.Log("Joint Broke!,force:" + breakForce);
    }

 3、OnParticleCollision

  当粒子碰到collider时被调用。这可以应用到游戏对象的伤害上(通过粒子给游戏对象带来的伤害)

  这个信息发送到所有附加到 WorldParticleCollider的脚本和被击中的碰撞体上(Collider)

  (1)传统粒子系统

    /// <summary>
    /// Legacy Particle System:
    /// 对所有被粒子碰撞的刚体组件施加一个力。
    /// 需要在Particle System的Collision→Type类型设置为World(粒子与世界中的对象相碰)
    /// 并开启sendCollisionMessage
    /// </summary>
    /// <param name="other"></param>
    void OnParticleCollision(GameObject other)
    {
        Rigidbody body = other.GetComponent<Rigidbody>();
        if (body)
        {
            //受力方向
            Vector3 direction = other.transform.position - transform.position;
            //方向标准化
            direction = direction.normalized;
            body.AddForce(direction * 5);
        }
    }

  (2)新版本粒子系统(Shuriken Particle System

  与传统粒子系统不同的是,他的信息发送到Particle Systems和Collider。

 

public ParticleSystem part;
    public List<ParticleCollisionEvent> collisionEvents;
    void Start()
    {
        //初始化组件(ParticleSystem)和事件
        part = GetComponent<ParticleSystem>();
        collisionEvents = new List<ParticleCollisionEvent>();
    }
    void OnParticleCollision(GameObject other)
    {
//other碰撞事件的对象,collisionEvents写碰撞事件的数组
        ParticlePhysicsExtensions.GetCollisionEvents(part, other, collisionEvents);

        //对刚体施加力
        Rigidbody rb = other.GetComponent<Rigidbody>();
        int i = 0;
        while(i<collisionEvents.Count)
        {
            if (rb)
            {
                //方向
                Vector3 pos = collisionEvents[i].intersection;
                //
                Vector3 force = collisionEvents[i].velocity * 10;
                //force相当于向量
                rb.AddForce(force);
            }
            i++;
        }
    }

或者:

public ParticleSystem part;
    public List<ParticleCollisionEvent> collisionEvents;
    void Start()
    {
        //初始化组件(ParticleSystem)和事件
        part = GetComponent<ParticleSystem>();
        collisionEvents = new List<ParticleCollisionEvent>();
    }
    void OnParticleCollision(GameObject other)
    {
        //定义一个整型变量存储粒子系统的Collision事件
        //other碰撞事件的对象,collisionEvents写碰撞事件的数组
        int numCollisionEvents = part.GetCollisionEvents(other,collisionEvents);

        //对刚体施加力
        Rigidbody rb = other.GetComponent<Rigidbody>();
        for (int i = 0; i < numCollisionEvents; i++)
        {
            if (rb)
            {
                Vector3 pos = collisionEvents[i].intersection;
                Vector3 force = collisionEvents[i].velocity * 10;
                rb.AddForce(force);
            }
        }
        //int i = 0;
        //while(i<numCollisionEvents)
        //{
        //    if (rb)
        //    {
        //        //方向
        //        Vector3 pos = collisionEvents[i].intersection;
        //        ////        Vector3 force = collisionEvents[i].velocity * 10;
        //        //force相当于向量
        //        rb.AddForce(force);
        //    }
        //    i++;
        //}
    }

  注(两段代码运行时都有错误:参数不能为空)

4、OnBecameVisible

  当renderer(渲染器)在任何相机上可见时(在物体进入摄像机时调用)。

5、 OnBecameInvisible

  renderer在任何摄像机上都不可见时调用。场景视图也要不可见才行。

6、OnLevelWasloaded

  当一个新关卡被载入时此函数被调用。

    void OnLevelWasloaded(int level)
    {
        if (level == 13)
            print("hello");
    }

 7、OnPreCull

  相机消隐场景之前调用。

   /// <summary>
    /// 把它赋给摄像机。所有被它渲染的物体都被翻转
    /// </summary>
    Camera cam;
    void Update()
    {
        cam = GetComponent<Camera>();
    }
    void OnPreCull()
    {
        //重置世界到相机空间的变换矩阵(世界矩阵到相机矩阵)
        cam.ResetWorldToCameraMatrix();
        //重置投影矩阵
        cam.ResetProjectionMatrix();
      //Matrix4x4:标准的4x4矩阵
        cam.projectionMatrix = cam.projectionMatrix * Matrix4x4.Scale(new Vector3(1, -1, 1));
    }
    //相机渲染场景之前被调用
    void OnPreRender()
    {
        //设置它为true我们可以看到翻转的物体
        GL.invertCulling = true;
    }
    //在相机完成场景渲染之后被调用
    void OnPostRender()
    {
        // 再设置它为false,因为我们不想作用于每个相机
        GL.invertCulling = false;
    }

8、OnPreRender

  相机渲染场景之前被调用。脚本附加到摄像机上

/// <summary>
    /// 这个脚本用于开启和关闭每个相机的雾
    /// </summary>
    private bool reverFogState = false;
    void OnPreRender()
    {
        reverFogState = RenderSettings.fog;
        RenderSettings.fog = enabled;
    }
    void OnPostRender()
    {
        RenderSettings.fog = reverFogState;
    }

9、OnPostRender

  相机完成场景渲染之后被调用。

    /// <summary>
    /// 该脚本附加在摄像机上,
    /// 反转目标颜色,在游戏模式下观察效果
    /// </summary>
    private Material mat;
    //常规渲染完成之后调用
    public void OnPostRender()
    {
        if (!mat)
        {
            //Unity有一个内置着色器(shader),对绘图很有用
            //我们现在想用一个混合模式来反转目标颜色
            var shader = Shader.Find("Hidden/Internal-Colored");
            mat = new Material(shader);
            mat.hideFlags = HideFlags.HideAndDontSave;
            //设置混合模式来反转目标颜色
            mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusDstColor);
            mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
            //关掉隐面消除
            mat.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
            mat.SetInt("_ZWrite", 0);
            mat.SetInt("_ZTest", (int)UnityEngine.Rendering.CompareFunction.Always);
        }
        //PushMatrix方法:将投影和模型视图矩阵都保存到矩阵堆栈中
        GL.PushMatrix();
        //LoadOrtho方法:帮助函数建立一个正交透视变换
        GL.LoadOrtho();

        //激活第一个着色器
        mat.SetPass(0);
        //在整个屏幕绘制一个方形(quad)
        GL.Begin(GL.QUADS);
        GL.Vertex3(0, 0, 0);
        GL.Vertex3(1, 0, 0);
        GL.Vertex3(1,1, 0);
        GL.Vertex3(0, 1, 0);
        GL.End();
        //把投影视图矩阵和模型视图矩阵弹出堆栈。
        GL.PopMatrix();
    }

 

posted @ 2017-08-27 20:51  LiuChangwei  阅读(866)  评论(0编辑  收藏  举报