2013-10-08 17:19:45 lzhq1982 阅读数 11836
  • Unity3D移动端实战经验分享

    主要是围绕资源加载效率的优化,文本文件加载,比如xml序列化读取,protobuf文件序列化,以及消息事件封装及应用,shader的优化及运用,移动端实时阴影的绘制。

    22506 人正在学习 去看看 姜雪伟

本系列文章由Aimar_Johnny编写,欢迎转载,转载请注明出处,谢谢。

http://blog.csdn.net/lzhq1982/article/details/12440045


第一次写博客,主要是想记录下自己学习unity3d的轨迹,如果能帮助观看的人,当然更好。

做移动互联网开发也将近两年了,先后用过cocos2d,cocos2d-x,一直在搞2d游戏,最近比较闲,自学了unity3d,unity3d对于我这种没有深厚的3d基础,却想开发3d游戏的人确实是不小的福音,好了,闲话少叙,基于所学的东西,我搞了个简单的demo,把能试验的技术都在这个demo里试验了一遍,我用的是unity4.2.0,所有的UI是用NGUI 2.6.4做的。下面上一下游戏截图。

登录界面(没有资源,只能用公司的产品了-时空领地,很好玩哦)(用NGUI的Sprite动画和屏幕分辨率自适应)



loading界面(继续公司产品)异步加载游戏场景及利用XML随机读取Tips介绍



下面进入战场,我们的美眉终于诞生了,怪物也由自己的AI自由行动



美眉奋力攻击(加上了刀光),顺便看下界面,全部是用NGUI2.6.4做的,包括英雄头像血条,中文字体,怪物头像血条,小地图,技能按钮



点击技能按钮,来个攻击特效



跟我们的湖光山色和瀑布来个合影吧



炫完了demo,本系列文章还有很多自己试验总结的核心技术,从下一篇博客开始,我们看看都是怎么实现的。

2018-05-07 13:22:02 qq_26270779 阅读数 310
  • Unity3D移动端实战经验分享

    主要是围绕资源加载效率的优化,文本文件加载,比如xml序列化读取,protobuf文件序列化,以及消息事件封装及应用,shader的优化及运用,移动端实时阴影的绘制。

    22506 人正在学习 去看看 姜雪伟

在开发中,尤其是跟模型与交互的时候,都会用到射线检测,这篇文章给大家分享一些射线检测的方法实现。

射线:射线是3D世界中一个点向一个方向发射的一条无终点的线,在发射轨迹中与其他物体发生碰撞时,它将停止发射 。
用途:射线应用范围比较广, 多用于碰撞检测(如:子弹飞行是否击中目标)、角色移动等。

相关API:

  1、Ray Camera.main.ScreenPointToRay(Vector3 pos)   返回一条射线Ray从摄像机到屏幕指定一个点

  2、Ray Camera.main.ViewportPointToRay(Vector3 pos)  返回一条射线Ray从摄像机到视口(视口之外无效)指定一个点

  3、Ray 射线类

  4、RaycastHit 光线投射碰撞信息

  5、bool Physics.Raycast(Vector3 origin, Vector3 direction, float distance, int layerMask)

  当光线投射与任何碰撞器交叉时为真,否则为假。

  bool Physics.Raycast(Ray ray, Vector3 direction, RaycastHit out hit, float distance, int layerMask)

  在场景中投下可与所有碰撞器碰撞的一条光线,并返回碰撞的细节信息()。

  bool Physics.Raycast(Ray ray, float distance, int layerMask)

  当光线投射与任何碰撞器交叉时为真,否则为假。

  bool Physics.Raycast(Vector3 origin, Vector3 direction, RaycastHit out hit,float distance, int layerMask)

  当光线投射与任何碰撞器交叉时为真,否则为假。

  注意:如果从一个球型体的内部到外部用光线投射,返回为假。

  参数理解:

  origin : 在世界坐标中射线的起始点

  direction: 射线的方向

  distance: 射线的长度

  hit: 使用c#中out关键字传入一个空的碰撞信息类,然后碰撞后赋值。可以得到碰撞物体的transform,rigidbody,point等信息。

  layerMask: 只选定Layermask层内的碰撞器,其它层内碰撞器忽略。 选择性的碰撞

  6、RaycastHit[] RaycastAll(Ray ray, float distance, int layerMask)

  投射一条光线并返回所有碰撞,也就是投射光线并返回一个RaycastHit[]结构体。

  下面一个利用射线做的拾取的小例子(将代码直接拖拽到主相机上)

using UnityEngine;

   using System.Collections;
   public class RayTest : MonoBehaviour {

       // Use this for initialization
       void Start () {

      }

       // Update is called once per frame
       void Update ()
       {
           if(Input.GetMouseButton(0))
           {
               Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//从摄像机发出到点击坐标的射线
               RaycastHit hitInfo;
              if(Physics.Raycast(ray,out hitInfo))
              {
                   Debug.DrawLine(ray.origin,hitInfo.point);//划出射线,只有在scene视图中才能看到
                   GameObject gameObj = hitInfo.collider.gameObject;
                   Debug.Log("click object name is " + gameObj.name);
                   if(gameObj.tag == "boot")//当射线碰撞目标为boot类型的物品 ,执行拾取操作
                   {
                       Debug.Log("pick up!");
                   }
               }
           }
       }
   }


2015-01-23 21:22:06 Gao_Liu_Yun 阅读数 917
  • Unity3D移动端实战经验分享

    主要是围绕资源加载效率的优化,文本文件加载,比如xml序列化读取,protobuf文件序列化,以及消息事件封装及应用,shader的优化及运用,移动端实时阴影的绘制。

    22506 人正在学习 去看看 姜雪伟

忽略碰撞


     有些时候我们不想让指定的两对象发生碰撞,即要忽略他们的碰撞。


    忽略碰撞情况下的限制:


1. 保存场景时忽略状态不能保存。

2. 只能在活动的对象物体上应用。如果用在失效的物体上,必须要调用一次physics.IgnoreCollision.


例如:定义一个球ball,当鼠标点击时,小球向前移动穿过墙


public GameObject ball;

void Start () {

     Physics.IgnoreCollision(ball.collider,this.collider);

                  }

void Update () {

        if(Input.GetButtonDown("Fire1")){

          ball.rigidbody.AddForce(0,0,100);

                     }

             }


射线


    射线是3D世界中一个点向一个方向发射无终点的线。在unity3d中我们发射的射线一旦与其他的碰撞器发生碰撞,射线将停止发射。在游戏制作过程中我们可以通过判断射线是否发生了碰撞,并且可以判断射线和谁发生了碰撞。应用范围非常广泛,如射击类游戏中用它来判断是否射中目标。

    我们要想在游戏中发射一条射线,必须要有两个元素,一个起始点,一个方向。

    Ray.origin:射线起点    Ray.direction:射线的方向

    创建一条射线的方法Ray (origin : Vector3, direction : Vector3)

    Origin是射线的起点,direction是射线的方向。


首先在场景中创建一个CUBE,创建一个c#文件,并输入如下代码:


 void Update () 

       {

          //定义一条射线,起点为Vector3.zero终点为物体坐标

          Ray ray=new Ray(Vector3.zero,transform.position);

          //定义一个光线投射碰撞

          RaycastHit hit;

          //发射射线长度为100

          Physics.Raycast(ray,out hit,100);

       //Scene中生成这条射线,起点为射线的起点,终点为射线与物体的碰撞点

          Debug.DrawLine(ray.origin,hit.point);   

       }


Debug.DrawLine()方法只在Scene视图中才可以看到


下面利用射线技术做的一个种豆游戏


当我们用鼠标点击地面,在我们点击地面的位置生成Prefab的实例,就像种豆子一样。

 


代码如下:


void Update () {

        if(Input.GetMouseButtonDown(0)){    //当鼠标点击时发生

            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//获取鼠标的位置

            RaycastHit hit;//定义一个射线

        if (Physics.Raycast(ray, out hit, 100)) {   //判断是否发生碰撞

            Instantiate(cube,hit.point,transform.rotation);//克隆一个方块并旋转

                 }

             }

         }

更多精彩请点击 http://www.gopedu.com/

2019-11-04 17:29:26 moon_goes 阅读数 18
  • Unity3D移动端实战经验分享

    主要是围绕资源加载效率的优化,文本文件加载,比如xml序列化读取,protobuf文件序列化,以及消息事件封装及应用,shader的优化及运用,移动端实时阴影的绘制。

    22506 人正在学习 去看看 姜雪伟

效果如下:

正常状态下
在这里插入图片描述
按下鼠标右键,镜头拉近,地上显示出轨迹(忽略这简陋的模型)在这里插入图片描述
我简略的把这个功能分成了3个部分。

1.摄像机移动部分:
按下右键的时候,camera位置调整到靠近人的位置,并伴随一声“嗖”的音效;
松开右键时,camera回归到正常视角。

2.在感知时人不能跑动(这部分是我自己加的规则,可以无视)

3.“提示轨迹”的显示和隐藏:
修改“提示轨迹”的layer,当感知时,layer改为摄像机可以检测到的层级,当不感知时,layer改为摄像机检测不到的层级。
当然轨迹的显示需要计算轨迹和人物的距离,在人物一定范围内,轨迹才会显示出来。

相机缩进和还原:

//放在update里
 if (Input.GetKeyDown(KeyCode.Mouse1))
        {
            chase.Play();//在按下右键一瞬间,播放音效
        }
        if (Input.GetKey(KeyCode.Mouse1))
        {
            isChase = true;//isChase是一个布尔值,用于控制人物能否跑动
            //缩进相机
            this.transform.localPosition = chasePos;//chasePos是预先测试好的一个感知时合适的位置
        }
        if (Input.GetKeyUp(KeyCode.Mouse1))
        {
            isChase = false;
            //还原相机
            this.transform.localPosition = originalPos;//originalPos是正常的相机位置
        }

“提示轨迹”的显示和隐藏:
轨迹我用几个cube形成路线(取消掉cube的collider),每个cube都挂载以下脚本,因为我把这些cube都统一放在了一个父物体下,所以还涉及了局部坐标转世界坐标,因为计算玩家和每个cube的距离需要用世界坐标来计算。

public class Tracks : MonoBehaviour
{
    GameObject pGO;
    float offset;
    void Start()
    {
        pGO = this.transform.parent.gameObject;
    }

    void Update()
    {
        //offset是玩家与cube的距离
        offset = Mathf.Abs((pGO.transform.TransformPoint(this.transform.localPosition) - PlayerAttris.instance.GetComponent<Transform>().position).magnitude);
        //cube显示的条件是玩家在进行感知并且cube和玩家的距离小于4(这个距离可以自己调节)
        if (CameraController.camcontroller.isChase && offset < 4)
        {
            //把cube的layer改成0(即default层)
            this.gameObject.layer = 0;
        }
        else if(!CameraController.camcontroller.isChase)
            //当玩家没有进行感知,把cube的layer改成14(自定义层)
            this.gameObject.layer = 14;//注意,在camera的culling Mask中要取消掉14层的渲染
    }
}
2019-11-19 08:36:38 weixin_42033622 阅读数 15
  • Unity3D移动端实战经验分享

    主要是围绕资源加载效率的优化,文本文件加载,比如xml序列化读取,protobuf文件序列化,以及消息事件封装及应用,shader的优化及运用,移动端实时阴影的绘制。

    22506 人正在学习 去看看 姜雪伟

射线

1、概念

射线是3D世界中一个点向一个方向发射的一条无终点的线,在发射轨迹中与其他物体发生碰撞时,它将停止发射

之前做的鼠标点击屏幕控制人物移动,就用到了射线,该案例是以鼠标点击的位置为起点,发出一条射线,

注意:鼠标点击的位置是摄像机镜头上的一个位置,然后以该位置垂直于摄像机屏幕发射射线。

Ray:射线

RaycastHit:射线碰撞信息类

2、创建射线

1.声明一个Ray,需要射线的起点,射线的方向。例:

Ray ray = new Ray(Vector3 start,Vector3 forword)

2.射线类和射线碰撞信息类总是一起出现,hitinfo用来储存射线碰撞的信息

RaycastHit hitinfo;

3.物理引擎(Physics)发出可与碰撞器碰撞的射线,下述语句返回值是布尔值,表示射线是否与物体发生碰撞。

(Physics.Raycast(ray,out hitinfo))

上述射线的声明方法外,还有下面这种很常用的声明方法:

Camera.main:获取场景中的主摄像机 ScreenPointToRay(Vector3 pos):以屏幕上一点为起点发射射线 Ray

Camera.main.ScreenPointToRay(Vector3 pos) );

以点pos为起点,垂直摄像机镜头发射射线

优点是可以获取点击屏幕上的点是点到哪个位置上了

5、获取射线碰撞的物体

void update(){
      RaycastHit hitinfo;    
            if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hitinfo))   //if检测射线是否碰撞到物体
            {nav.destination = hitinfo.point;  //nav走到射线打到的位置上 }


}

hitinfo.point:就是射线与物体碰撞的位置

【与君共勉】

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