2014-11-26 11:56:18 asd237241291 阅读数 46293
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 QQ群:【Unity3D(AR/VR) 334163814】【Unity3D(游戏) 119706192】 本文链接地址: 多种播放音效的方式


AudioListener组件默认绑定在主摄像机上,这个组件的功能相当于耳朵,用来听声音的。

1.背景音乐

选中音乐文件,建议不勾选3D Sound选项。
在Main Camera下创建一个空物体,添加AudioSound组件,AudioClip选择要播放的音乐。
Loop必须勾选,循环播放。
勾选PlayOnAwake,场景一进来就开始播放,如果不勾选找个合适时机Play()。

2.NGUI的UIPlaySound

在摄像机直接添加个AudioSource组件,这个组件不挂任何AudioClip。(UIPlaySound将在这个组件上播放音效,在这里调整Volume能控制所有UIPlaySound的音量大小。UIPlaySoundVolume属性只控制自己的音量,最后的音量是这两个音量值相乘。)

3.碰撞触发的音效

public AudioClip AC;
OnCollisionEnter(Collision collision)
//或者OnTriggerEnter(Collider collider)
{
    //被撞得物体原点发出声音(第二个参数用来设置发出声音的世界坐标,不要离AudioListener太远)
    AudioSource.PlayClipAtPoint(AC, transform.localPosition);
}

4.Animation动作回调的音效

public class AnimationCallSound : MonoBehaviour 
{
    //防止同一个动作多次注册回调
    public static List<string> isHaveevent = new List<string>();

    //调用事件
    public float EventTime;
    //要播放的音效(必须绑定一个AudioSource组件)
    public AudioSource AS;

	void Start () 
    {
        if (AS == null)
            Debug.LogError("没有绑定音效");
        AddEvent();
        //防止场景内动作相同的物体动作同步
        Invoke("PlayAnim",Random.Range(0.1f,5.5f));
	}
    void PlayAnim()
    {
        animation.Play();
    }

	
    //给Animation动画注册回调事件
    void AddEvent()
    {
        foreach (string name in isHaveevent)
        {
            if (animation.clip.name == name)
                return;
        }
        
        AnimationEvent auidoEvent = new AnimationEvent();
        auidoEvent.time = EventTime;
        auidoEvent.functionName = "PlayAudio";

        animation.clip.AddEvent(auidoEvent);
        isHaveevent.Add(animation.clip.name);
        Debug.Log("add " + animation.clip.name + " Event!");
    }

    public void PlayAudio()
    {
        AS.Play();
    }
}


2016-03-24 16:07:07 begonia__z 阅读数 10240
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

   AR为现在是虚拟现实较为火爆的一个技术,其中有个比较炫酷的就是AR涂涂乐的玩法,这个技术可以把扫描到的图片上的纹理 粘贴到模型上实现为模型上色的功能,但是我们需要怎么才能实现其功能呢?大体的方法是将扫描到图片保存成纹理,在将纹理保存到模型的材质球上然后实现上色的功能。

   那么有什么方式可以实现这个功能呢?我在参考的EsayAR的Demo以及在网上查找的方法基本都是采用通过Shader进行图片的处理,因此在这样的条件下,若有多个模型的UV张开图就要写不同的Shader进行进行图片的处理,这样的方式并不方便。那么有没有方法可以不写Shader来实现图片上UV展开图的颜色准确粘贴到模型上呢?于是我想为什么不可以在屏幕上设置一个扫描对准框,然后将扫描框的的内容保存成纹理呢?

  那么我先配置好AR的环境,这里我用EsayAR来制作AR涂涂乐的效果,这里为了方便我直接用EsayAR Coloring3D的例子来做这个效果吧!我们先去创建一个空的Gameobject将EsayAR例子中的EasyImageTargetBehaviour类拖入空的GameObject里然后我们将其改名为ImageTargetNamecard,设置好我们的识别图片红色框是图片名字,黄色框是图片放置的位置,记得要Storage属性要设置成Assets,如下图所示:

   然后将模型拖入到刚刚创建的ImageTargetNamecard下这样我们就做好了识别图以及模型,摆放的模型要注意的是这个模型必须是要有纹理展开图的模型,然后作为模型的识别图的图片必须对是对应着其纹理的展开的图片,例子里面我是使用一个展开过纹理的Cube模型,其中色块的位置正是UV展开的位置,展开的纹理图片如图下图所示:


   现在弄好了AR环境了,那么我们开始做扫描用的对准框吧,这里我用的是UGUI来制作对准框,这里我给对焦框设定好大小,因为我使用的识别图片是1024*1024的所以我们的对焦框也要弄成正方形的520*520就可以了,然后在弄一个按钮在对准后帮模型“上色”!做好的效果大体就如下图所示一样:


   那么开始写代码吧!这里我们在模型上添加一个InterceptTexture脚本,脚本内容如下:

using System;
using UnityEngine;
using System.Collections;
using System.IO;
using EasyAR;
using Image = UnityEngine.UI.Image;

public class InterceptTexture : MonoBehaviour {

    public Image scanTexture;
    public bool isrealRender = false;
    private Camera scanCamera;
    private RenderTexture renderTexture;
    private string pipingID;
    private string scanPath;
    private Rect scanRect;
    private bool isScanTexture = false;//是否开启实时渲染
    //ImageTargetBaseBehaviour targetBehaviour;


    // Use this for initialization
    void Start()
    {
        scanPath = Application.dataPath + "/StreamingAssets/Drwaing/";
        scanRect = new Rect(scanTexture.rectTransform.position.x - scanTexture.rectTransform.rect.width / 2, scanTexture.rectTransform.position.y - scanTexture.rectTransform.rect.height / 2,
           (int)scanTexture.rectTransform.rect.width, (int)scanTexture.rectTransform.rect.height);
        //targetBehaviour = GetComponentInParent<ImageTargetBaseBehaviour>();
        gameObject.layer = 31;
        
    }

    void Renderprepare()
    {
        if (!scanCamera)
        {
            GameObject obj = new GameObject("ScanCamera");
            scanCamera = obj.AddComponent<Camera>();
            obj.transform.parent = transform.parent;
            scanCamera.hideFlags = HideFlags.HideAndDontSave;
        }
        scanCamera.CopyFrom(Camera.main);
        scanCamera.depth = 0;
        scanCamera.cullingMask = 31;
        if (!renderTexture)
        {
            renderTexture = new RenderTexture(Screen.width, Screen.height, -50);
        }
        if (!isScanTexture)
        {
            scanCamera.targetTexture = renderTexture;
            scanCamera.Render();
        }
        if(isrealRender)
            GetComponent<Renderer>().material.SetTexture("_MainTex", renderTexture);
        //RenderTexture.active = renderTexture;
        //StartCoroutine(ImageCreate());
       
    }

    void OnWillRenderObject()
    {
        Renderprepare();
    }

    void OnDestroy()
    {
        if (renderTexture)
            DestroyImmediate(renderTexture);
        if (scanCamera)
            DestroyImmediate(scanCamera.gameObject);
    }

    public void ScanTextureClick()
    {
        StartCoroutine(ImageCreate());
    }

    IEnumerator ImageCreate()
    {
        isScanTexture = true;
        if (isScanTexture)
        {
            scanCamera.targetTexture = renderTexture;
            scanCamera.Render();
        }
        RenderTexture.active = renderTexture;
        Texture2D scantTexture2D = new Texture2D((int)scanRect.width, (int)scanRect.height, TextureFormat.RGB24, false);
        yield return new WaitForEndOfFrame();
        scantTexture2D.ReadPixels(scanRect, 0, 0, false);
        scantTexture2D.Apply();

        scanCamera.targetTexture = null;
        RenderTexture.active = null;
        GameObject.Destroy(renderTexture);

        byte[] bytes = scantTexture2D.EncodeToPNG();
        string savePath = scanPath + gameObject.name + ".png";
        File.WriteAllBytes(savePath,bytes);
        isScanTexture = false;
        isrealRender = false;        ///关闭实时渲染
        this.gameObject.GetComponent<Renderer>().material.SetTexture("_MainTex", scantTexture2D);
        Debug.Log("截图完成!");
    }
}
  这里使用的UGUI来制作的扫描框,因此如果用NGUI的同学要自己改一下代码哟!因为公司极却摄像头,我就不做实时演示的截图了

  通过对准框截图下来的图片如下:


   然后看看我们的模型没贴纹理之前的样子,如下图所示:


   然后是先附上贴非裁剪的正常纹理图,第二张是我们截图下来的做纹理的图片:



   因为测试的时候用手机打开识别图,导致颜色有点变了,但是大体上位置都没有错!好了测试成功了~~~运行测试的时候千万被手抖哟!不如就没办法完美的对好UV位置!~~

  因为是刚刚开始接触AR不久,所以可能做的不好望大家可以多多交流~第一次在公司写技术文章,写的不好请多多包含~

                                                                                                                                                                                                                                                                                            --Bě9oniǎ     

这里还有现在普遍的shader上色方法...

2014-01-15 17:31:49 asd237241291 阅读数 40924
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 QQ群:【Unity3D(AR/VR) 334163814】【Unity3D(游戏) 119706192】 本文链接地址: 动态实例化Prefab


之前写过一篇“Unity3D NGUI动态创建按钮”不少人按照我文章中介绍的方法来动态创建按钮,文章那种做法并不好。现在写一遍新的文章来教大家用Prefab的方式来动态创建NGUI按钮(也可以是任何GameObject)。


1.首先要预制好我们要创建的物体:

a.首先创建一个游戏物体。


b.自定义样式并添加自己需要的脚本。


我添加了一个测试代码,当点击按钮的时候把按钮文字替换为buttonID。
using UnityEngine;
using System.Collections;

public class TestButton : MonoBehaviour 
{
    public int ButtonID = 0;

    //点击把按钮问题替换为ButtonID
    void OnClick()
    {
        UILabel buttonLable = GetComponentInChildren<UILabel>();
        buttonLable.text = ButtonID.ToString();
    }
}

c.讲制作好的物体创建为Prefab。


2.动态创建脚本。

a.脚本。

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

public class TestCreat : MonoBehaviour 
{
    public GameObject ButtonPre;
    public int CreatCount = 3;
    public float PosY = 0;
    public float Padding = 40;

    //存储所有动态添加的按钮
    [HideInInspector]
    public List<TestButton> Buttons = new List<TestButton>();


    void Start()
    {
        CreatButton();
    }

    void Update()
    {
        //按下空格键,删除id为1的按钮
        if (Input.GetKeyDown(KeyCode.Space))
        {
            //不能在foreach里面直接删除元素,所以把要删除的元素先记录下来,foreach结束后再删除。
            TestButton deleteTB = null;
            foreach (TestButton item in Buttons)
            {
                if (item.ButtonID == 1)
                {
                    deleteTB = item;
                    break;
                }
            }
            if (deleteTB != null)
                Destroy(deleteTB.gameObject);
        }
    }

    void CreatButton()
    {
        Buttons.Clear();
        for (int i = 0; i < CreatCount; i++)
        {
            Buttons.Add(AddButton());
        }
    }

    TestButton AddButton()
    {
        GameObject go = NGUITools.AddChild(this.gameObject, ButtonPre);
        go.name = "动态" + Buttons.Count;
        go.transform.localPosition = new Vector3(go.transform.localPosition.x, PosY + Padding * Buttons.Count, go.transform.localPosition.z);

        TestButton tb = go.GetComponent<TestButton>();
        tb.ButtonID = Buttons.Count;
        return tb;
    }
}

b.赋值。

将TestCreat脚本绑定在要创建动态物体的父级。
将做好的Prefab绑定到ButtonPre属性。
之后隐藏掉场景内手动设置的那个原始物体。


3.结果测试。

a.开始运行,创建了CreatCount个按钮,分别取名,Y轴由PosY开始,每个按钮间距Padding。


b.点击按钮,按钮Label改变为ButtonID。


c.按下空格键删除ButtonID为1的按钮。




2015-04-16 00:10:04 yuxikuo_1 阅读数 2224
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 QQ群:【Unity3D(AR/VR) 334163814】【Unity3D(游戏) 119706192】 本文链接地址: 动态实例化Prefab


之前写过一篇“Unity3D NGUI动态创建按钮”不少人按照我文章中介绍的方法来动态创建按钮,文章那种做法并不好。现在写一遍新的文章来教大家用Prefab的方式来动态创建NGUI按钮(也可以是任何GameObject)。


1.首先要预制好我们要创建的物体:

a.首先创建一个游戏物体。


b.自定义样式并添加自己需要的脚本。


我添加了一个测试代码,当点击按钮的时候把按钮文字替换为buttonID。
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class TestButton : MonoBehaviour   
  5. {  
  6.     public int ButtonID = 0;  
  7.   
  8.     //点击把按钮问题替换为ButtonID  
  9.     void OnClick()  
  10.     {  
  11.         UILabel buttonLable = GetComponentInChildren<UILabel>();  
  12.         buttonLable.text = ButtonID.ToString();  
  13.     }  
  14. }  

c.讲制作好的物体创建为Prefab。


2.动态创建脚本。

a.脚本。

  1. using UnityEngine;  
  2. using System.Collections;  
  3. using System.Collections.Generic;  
  4.   
  5. public class TestCreat : MonoBehaviour   
  6. {  
  7.     public GameObject ButtonPre;  
  8.     public int CreatCount = 3;  
  9.     public float PosY = 0;  
  10.     public float Padding = 40;  
  11.   
  12.     //存储所有动态添加的按钮  
  13.     [HideInInspector]  
  14.     public List<TestButton> Buttons = new List<TestButton>();  
  15.   
  16.   
  17.     void Start()  
  18.     {  
  19.         CreatButton();  
  20.     }  
  21.   
  22.     void Update()  
  23.     {  
  24.         //按下空格键,删除id为1的按钮  
  25.         if (Input.GetKeyDown(KeyCode.Space))  
  26.         {  
  27.             //不能在foreach里面直接删除元素,所以把要删除的元素先记录下来,foreach结束后再删除。  
  28.             TestButton deleteTB = null;  
  29.             foreach (TestButton item in Buttons)  
  30.             {  
  31.                 if (item.ButtonID == 1)  
  32.                 {  
  33.                     deleteTB = item;  
  34.                     break;  
  35.                 }  
  36.             }  
  37.             if (deleteTB != null)  
  38.                 Destroy(deleteTB.gameObject);  
  39.         }  
  40.     }  
  41.   
  42.     void CreatButton()  
  43.     {  
  44.         Buttons.Clear();  
  45.         for (int i = 0; i < CreatCount; i++)  
  46.         {  
  47.             Buttons.Add(AddButton());  
  48.         }  
  49.     }  
  50.   
  51.     TestButton AddButton()  
  52.     {  
  53.         GameObject go = NGUITools.AddChild(this.gameObject, ButtonPre);  
  54.         go.name = "动态" + Buttons.Count;  
  55.         go.transform.localPosition = new Vector3(go.transform.localPosition.x, PosY + Padding * Buttons.Count, go.transform.localPosition.z);  
  56.   
  57.         TestButton tb = go.GetComponent<TestButton>();  
  58.         tb.ButtonID = Buttons.Count;  
  59.         return tb;  
  60.     }  
  61. }  

b.赋值。

将TestCreat脚本绑定在要创建动态物体的父级。
将做好的Prefab绑定到ButtonPre属性。
之后隐藏掉场景内手动设置的那个原始物体。


3.结果测试。

a.开始运行,创建了CreatCount个按钮,分别取名,Y轴由PosY开始,每个按钮间距Padding。


b.点击按钮,按钮Label改变为ButtonID。


c.按下空格键删除ButtonID为1的按钮。

2020-01-10 14:00:54 kwame211 阅读数 144
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

在虚拟现实大热的今天,开发者界也出现了“甜豆花”与“咸豆花”之争。在游戏开发者制作游戏时,面对都是免费、都支持各大平台的UE4和Unity 3D,选择何种游戏引擎,似乎有点难以抉择,左手UE4,右手Unity 3D。今天本文为大家做一点详细分析,希望能为大家带来一些启发。

Unity 3D

Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。Unity利用交互的图型化开发环境为首要方式,其编辑器运行在Windows 和Mac OS X下,可发布游戏至Windows、Mac、Wii、iPhone、WebGL(需要HTML5)、Windows phone 8和Android平台。也可以利用Unity web player插件发布网页游戏,支持Mac和Windows的网页浏览。

Unity 3D的优势

虚拟现实游戏开发者的轻量级工具,目前虚拟现实游戏开发者的首选游戏引擎。时下大部分的VR游戏开发者都是从原Unity 3D开发者转型而来,由于能够快速上手,在VR方面的学习成本比较低,因而受到了广大开发者的热捧。

Unity 3D安装、调试和打包方便,配置VR项目十分简单,文档完善。Unity3D配套了很多东西供开发者使用,基本可以靠Marketplace买来的东西搭建原型,甚至某些最终业务的核心组件也可以用买来的东西,极大的降低了开发成本。比如你可以把整个Material换成Alloy、用Ngui替代UI系统,如果你要做个赛车游戏,你能找到从模型、音效、材质,到控制系统等一切。

Unity 3D的劣势

内建工具不够完善,渲染差,光照系统糟糕,阴影Bake有Bug,只能勉强达到2A游戏入门水平对于控制器支持较差,一些如手柄震动、VR控制器空间定位的功能引擎未集成,需要第三方插件或额外代码没有材质编辑器,需要第三方插件,Prefab不支持继承,没有内建的Level Stream支持。

Unity 3D最大的问题都不在于以上,而在于官方对于开发者的技术支持不够。有开发者网友表示,曾经在VR Demo上进行一项底层优化时,在缺少渲染使用的关键数据时,向官方寻求技术支持,结果一个“没有这样的接口”就被打发了。对开发者而言,这可不是什么好消息。

Unreal Engine 4

UE4是由全球顶级游戏EPIC公司虚幻引擎的最新版本,EPIC中国唯一授权机构GA游戏教育基地。UE4支持DirectX 11、物理引擎PhysX、APEX和NVIDIA 3D技术,以打造非常逼真的画面。UE4是一个面向虚拟现实游戏开发、主机平台游戏开发和DirectX 11个人电脑游戏开发的完整开发平台,提供了游戏开发者需要的大量的核心技术、数据生成工具和基础支持。登陆设备包括PC,主机,手机和掌机。

UE4的优势

作为后起之秀,UE4在虚拟现实VR游戏开发者界大出风头,其强大的开发能力和开源策略,瞬间吸引了大量VR游戏开发者的目光。目前,大量以UE4开发的VR游戏已经登陆各大平台,而VR爱好者的普遍评价都是虚幻4引擎游戏在游戏画面和沉浸体验方面要明显优于Unity3D 游戏。

UE4画面效果完全达到3A游戏水准,光照和物理渲染即便在缩水的状况下也足以秒杀Unity蓝图系统。UE4让游戏策划不用再写劳神费力编辑代码,其强大的材质编辑器实在让开发者们大呼德玛西亚,各种官方插件齐全也让开发者不用在自编第三方插件并担心兼容接口问题。更重要的是针对虚拟现实游戏,UE4为手柄、VR控制器提供了良好支持。而UE4提供的各种游戏模版,让其与Blueprint配合做原型甚至比Unity更快。

UE4的劣势

C++语言是第一个令众多开发者头痛的东西。对于主机平台的支持不够,开发PS4游戏需要重新编译引擎,光拉代码就需要至少一个小时,使用12核服务器,24线程同时编译都需要二三十分钟,创建新项目大概又要编译十多分钟。如果切换平台,要编译几千到上万个Shader,安装、调试和打包不方便,需要的时间明显超过Unity很多。

 

同样,UE4最大的问题也不在以上,而在于学习成本高。UE4现有的虚拟现实游戏开发者中普及度并不高,开发者对于这款引擎的了解程度和使用经验明显不够。UE4各子模块虽然功能强大,但操作复杂,部分功能甚至没有任何文档,已有文档的功能文档同样不够完善,加大增加了开发者的学习难度,影响开发者的使用体验。UE4开发成本高是出了名的,某国内3A团队做了个10分钟的VR Demo,一千多万眨眨眼就烧掉了。UI设计器非常之难用,VR下的一些best practice也缺乏文档和例子,给人的感觉就是UE4在和开发者以期摸石头过河,明显不能让开发者省心。
 

Unity3D教程

阅读数 2042

Unity3D常用插件

阅读数 442