2014-04-20 22:32:23 qinyuanpei 阅读数 11798
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4646 人正在学习 去看看 张刚

       大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei

       相信大家在安装完Unity3D后做的第一件事情一定是浏览官方的示例项目《愤怒的机器人》,这个游戏在场景渲染及光照阴影特效等方面都有不错的表现。那么不知道大家还记不记得这样一个场景,当玩家操控我们的游戏角色——机器人时,当机器人靠近游戏场景中的门时,门会自动打开,而当机器人离开门时,门会自动关闭。那么,我们今天就来一起实现这样一个简单的功能。通过题目大家一定知道了这个功能的实现是基于Trigger的。Trigger在Unity3D中称为触发器,当一个碰撞器勾选了isTrigger选项后,即变成了触发器。触发器和碰撞器的区别在于碰撞器通过OnCollisionEnter/Stay/Exit()三个方法进行响应且会对参与到碰撞中的物体产生力的作用。而触发器则通过OnTriggerEnter/Stay/Exit()三个方法来响应且不会对参与到触发的物体产生力的作用。关于触发器和碰撞器的内容,大家可以参考这篇文章:http://game.ceeger.com/Components/class-BoxCollider.html

       好了,下面请大家跟随我一起来学习如何在Unity3D中实现基于Trigger的触发式动画,首先我们创建如下的场景:


        场景中的地面和墙体、门均有Cube构成,这里我们把地面、墙体的盒子碰撞器全部移除,避免它们对我们的程序产生干扰。首先我们编写两段脚本来控制门从左向右移动、从右向左移动的动画:

	//开门动画
	private void OpenDoorAni()
        {
	  if(transform.position.x<=1.8F)
	  {
		transform.Translate(Vector3.right * Time.deltaTime * 1.5F);
	  }
        }
	//关门动画
	private void CloseDoorAni()
	{
	  //等待5秒后再关门,避免角色与门发生碰撞
	  StartCoroutine("Wait");
	  if(transform.position.x>=0)
	  {
		transform.Translate(Vector3.left * Time.deltaTime * 1.5F);
	  }
	}
	

         代码基本上很容易理解,就是分别从左向右、从右向左移动门啦!接下来,我们给我们的角色加上一个球体碰撞器并勾选isTrigger选项,为什么选择球体碰撞器呢,因为这样角色进入触发和退出触发的时候,都是和门的盒子碰撞器相切的。在关门的时候延迟两秒是为了给玩家一个控制角色的反应时间,避免和门发生碰撞。这里要注意的是角色是带刚体的。

         好了,接下来我们编写触发这一块的代码:

	
	void OnTriggerEnter(Collider mCollider)
	{
	  Debug.Log(mCollider.gameObject.tag);
	  if(mCollider.gameObject.tag=="Player")
	  {
	    Triggered=true;
	  }
	}
	
	void OnTriggerExit(Collider mCollider)
	{
	  if(mCollider.gameObject.tag=="Player")
	  {
	    Triggered=false;
	  }
	}
	
       我们在这里是通过改变一个bool型的标志变量来标记角色是否引起了触发,当引起了触发的时候执行开门的动画,退出除了触发的时候执行关门的动画。这一部分我们放在Update()方法里:

	
	void Update () 
	{
	  if(Triggered)
	  {
	    OpenDoorAni();
	  }else if(!Triggered)
	  {
		CloseDoorAni();
	  }
	}

      最后给出全部代码:

using UnityEngine;
using System.Collections;

public class AniScripts : MonoBehaviour {
	
    //定义门的移动速度
	public float mSpeed=1.5F;
	//定义门的标志变量
	private bool Triggered=false;
	
	void Update () 
	{
	  if(Triggered)
	  {
	    OpenDoorAni();
	  }else if(!Triggered)
	  {
		CloseDoorAni();
	  }
	}
	
	//开门动画
	private void OpenDoorAni()
    {
	  if(transform.position.x<=1.8F)
	  {
		transform.Translate(Vector3.right * Time.deltaTime * 1.5F);
	  }
    }
	//关门动画
	private void CloseDoorAni()
	{
	  //等待5秒后再关门,避免角色与门发生碰撞
	  StartCoroutine("Wait");
	  if(transform.position.x>=0)
	  {
		transform.Translate(Vector3.left * Time.deltaTime * 1.5F);
	  }
	}
	
	void OnTriggerEnter(Collider mCollider)
	{
	  Debug.Log(mCollider.gameObject.tag);
	  if(mCollider.gameObject.tag=="Player")
	  {
	    Triggered=true;
	  }
	}
	
	void OnTriggerExit(Collider mCollider)
	{
	  if(mCollider.gameObject.tag=="Player")
	  {
	    Triggered=false;
	  }
	}
	
	
	IEnumerator Wait()
	{
		//等待5秒在执行
		yield return new WaitForSeconds(5);
	}
	
	
}

        一起来看看效果演示吧:


         喜欢我的博客请记住我的名字:秦元培,我的博客地址是:blog.csdn.net/qinyuanpei
         转载请注明出处,本文作者:秦元培,本文出处:http://blog.csdn.net/qinyuanpei/article/details/24198893


     

2019-01-20 18:17:42 qq_42292831 阅读数 5230
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4646 人正在学习 去看看 张刚

Official Doc:https://docs.unity3d.com/ScriptReference/MonoBehaviour.html



触发器(Trigger)是用来触发事件:

当绑定着碰撞器的游戏对象进入触发器区域的时候,会运行触发器对象上的MonoBeavior中的OnTriggerEnter()函数;

当其处在触发器区域的时候会运行OnTriggerStay()函数,每帧调用一次OnTriggerStay()函数;

当其离开触发器区域的时候会运行OnTriggerExit()函数;



Step1:

创建一个空的游戏物体(改名为Trigger),并添加Box Colider组件,勾选Is Trigger

Step2:

调节Trigger的位置以及大小

Step3:

新建测试脚本,添加到Trigger上

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Trigger_A : MonoBehaviour {

    void OnTriggerEnter(Collider other)
    {
        Debug.Log(Time.time + ":进入该触发器的对象是:" + other.gameObject.name);
    }
    void OnTriggerStay(Collider other)    //每帧调用一次OnTriggerStay()函数
    {
        Debug.Log(Time.time + "留在触发器的对象是:" + other.gameObject.name);
    }
    void OnTriggerExit(Collider other)
    {
        Debug.Log(Time.time + "离开触发器的对象是:" + other.gameObject.name);
    }
}

 

2014-06-21 03:17:01 iteye_5020 阅读数 263
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4646 人正在学习 去看看 张刚

大致研究了下,可以有这几种情况:

  • 如果物理视觉上有碰撞,则在OnCollisionEnter中实现。要求双方都具有Rigidbody,双方都是可见的物体。应用上偏向于可见的碰撞。
  • 如果物体经过某一不可见区域,比如踩点事件,则使用OnTriggerEnter。要求至少1方拥有Rigidbody,并且有1方加入Trigger。应用上偏向于事件触发(顾名思义),比如Player进入某个区域或是站到某个位置。

另外,OnCollisionEnter传递的是collision对象,通过此对象可以获得相应的碰撞体的transform、rigidbody、gameObject等对象;OnTriggerEnter传递的则是collider碰撞器,其可以获得碰撞器的材质等信息。此外,collision对象中包含了collider对象。比较复杂。

其他待定。。。

2015-04-09 19:32:31 baizihan 阅读数 352
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4646 人正在学习 去看看 张刚

【Unity3d】学习笔记(3)

目录

前言

我学习Unity3d的方法是通过实战案例来学习,碰到不知道的概念在反过来查找并理解概念的意思。我认为这样比单纯的了解一大堆概念之后在开始实践要更有趣,更有动力,理解也更深。但是,同时我也认为这种方法比较适合有一些编程经验的人,一些程序设计的通用概念你可能已经驾轻就熟,而Unity特有的概念可能与你熟知的概念有相似性,关联他们,有助于你加深理解。

正文

今天完成了所有游戏逻辑,遇到的新概念不多,但依然有新技能Get:

  • 导航网格代理 (Nav Mesh Agent)
  • 触发器Trigger

导航网格代理 (Nav Mesh Agent)

导航网格代理组件与寻路结合使用,是放置有关此代理如何对导航网格进行导航的信息的位置。可以在组件 (Component)->导航 (Navigation)->导航网格代理 (Nav Mesh Agent) 中访问它。游戏中使用该组件使Enemy可以自动搜寻角色所在位置。对场景烘培后即可使用代理。

anim = this.GetComponent<Animator> ();
if (Vector3.Distance (transform.position, player.position) < 1.4f) {
            agent.Stop();
            anim.SetBool("Move",false);
        } else {
            agent.SetDestination(player.position);
            anim.SetBool("Move",true);
        }

(实际代码以GitHub为准,此处仅为演示)

更多关于导航网格代理(NavMesh Agent)的信息可以直接通过官方文档查看。

触发器Trigger

游戏中Enemy的攻击使用了触发器。触发器是碰撞体(Collider)的一个属性,如果启用,此碰撞体则用于触发事件,会由物理引擎忽略。为Enemy的GameObject添加了一个Sphere Collider后将其半径设置少大,并设置为触发器:
设置为Trigger

然后添加OnTriggerStay函数:

public void OnTriggerStay(Collider col){
        //not hit player or already dead
        if (!(col.tag == Tags.player) || enemyHealth.hp <= 0)
            return;
        timer += Time.deltaTime;
        if (timer >= attackTime) {
            timer -= attackTime;
            col.GetComponent<PlayerHealth>().TakeDamage(attack);
        }
    }

这样就实现了Enemy的攻击了。由于Sphere Collider半径过大,主角射击的射线碰撞会检测到Sphere Collider上,所以要在Edit->Project Settings->Physics->取消掉RayCast Hit Triggers:
这里写图片描述

更多详细信息可参考官方文档

PS:做游戏真是开心~

2014-02-25 14:35:48 memmorryy 阅读数 1157
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4646 人正在学习 去看看 张刚

Unity3d 主要由Trigger和Collison 两种碰撞检测:

(1)
检测Trigger:双方都有Collider。双方至少有一个Rigidbody(任意一方都可以),有一个Trigger(任意一方都可以).
若只有一个Rigidbody,则碰撞时,该Rigidbody一定要是运动的。
碰撞后发出的OnTriggerEnter,OnTriggerStay,OnTriggerExit都可以在双方所附加的脚本上接收。其中的参数Collider other是碰撞的另一方的Collider
常用方法如下:
OnTriggerEnter 进入时
OnTriggerExit 离开时
OnTriggerStay 处于时

今天跟这教程做合金弹头,注意到当主角遭受敌人近身刺杀攻击时使用OnTriggerStay 方法,当遭受敌人子弹或炮弹攻击时,采用OnTriggerEnter 方法:

近身刺杀:
void OnTriggerStay(Collider other)
    {
        myTime3 += Time.deltaTime;
        if (myTime3 > 1 && other.tag == "enemy")
        {
            killed = true;
            myTime3 = 0;
            Destroy(other.gameObject);
        }
    }
远程炮弹:
  void OnTriggerEnter(Collider other)
    {
        myCamera=GameObject.Find("Main Camera");  //获取主摄像机,在之后产生音效时在摄像机处产生,以达到音效声音效果更好
        if(other.tag=="gift1")                                           //合金弹头中子弹包
        {
            AudioSource.PlayClipAtPoint(giftSound,new Vector3(myCamera.transform.position.x,0,-10));
            Destroy(other.gameObject);
        }
        if (other.tag == "gift2")                                     //合金弹头中医疗包
       
        {
            AudioSource.PlayClipAtPoint(giftSound, new Vector3(myCamera.transform.position.x, 0, -10));
            Destroy(other.gameObject);
        }
      //合金弹头中各种敌人发出的炸弹
        
        if (other.tag == "bombExplosion")


        {
            killed = true;
            Destroy(other.gameObject);
            GameObject enemy2 = GameObject.Find("enemy2");
            Enemy2Controller myEnemy2Controller = enemy2.GetComponent<Enemy2Controller>();
            myEnemy2Controller.SetTime(-3.0f);
          
        }
        else if (other.tag == "jetExplosion")
        {
            killed = true;
            Destroy(other.gameObject,0.5f);
            GameObject myJet = GameObject.Find("jets");
            JetController myJetController = myJet.GetComponent<JetController>();
            myJetController.SetTime(-2.0f);


        }
        else if (other.tag == "tankFire")
        {
            Instantiate(tankFireExplosion, other.transform.position + new Vector3(-0.1f, 0.0f, -0.1f), transform.rotation);
            killed = true;
            Destroy(other.gameObject, 0.5f);
            GameObject myTank = GameObject.Find("tank");
            TankController myTankController = myTank.GetComponent<TankController>();
            myTankController.SetTime(-2.0f);


        }   

}




(2)
检测Collision:双方都没有Trigger。双方至少有一个非kinematic的Rigidbody。
若只有一个Rigidbody,则碰撞时,该Rigidbody一定要是运动的。
碰撞后发出的OnCollisionEnter,OnCollisionStay,OnCollisionExit都可以在双方所附加的脚本上接收。其中的参数Collision collision的各个属性collider,gameObject,rigidbody(若无则为null),transform,均为碰撞另一方的属性。

没有更多推荐了,返回首页