• Unity3D教程:将3D坐标转成2D坐标的方法。3D坐标在Unity中称作World Space,2D坐标称作Screen Space, 是以pixel为基准,以iPad 1024 x 768(4:3)的解析度为例子: 左上角是 (0,0) 右下角是(1024,768) Unity...

    Unity3D教程:将3D坐标转成2D坐标的方法。3D坐标在Unity中称作World Space,2D坐标称作Screen Space, 是以pixel为基准,以iPad 1024 x 768(4:3)的解析度为例子:

    左上角是 (0,0)

    右下角是(1024,768)

    Unity3D教程:将3D坐标转成2D坐标的方法

    Unity3D教程:将3D坐标转成2D坐标的方法

    功能制作:点击画面中的3D方块 然後在该方块的中心位置产生相对应的GUI

    主要是应用此功能: camera.WorldToScreenPoint ();

    将以下的JavaScript加在Camera物件下。

     

    Unity3D教程:将3D坐标转成2D坐标的方法

    Unity3D教程:将3D坐标转成2D坐标的方法

    1.Raycast点击设定:让你可以用滑鼠(PC)/手指(iPad, mobile devices)做点击测试。

    2.用“tower”标签名称来区隔不同的3D物件。

    3.用此功能取得所点击的3D物件的x,y,z坐标(world space) 然后再透过camera.WorldScreenPoint()转换成screen space的2D坐标。

    4.然后我们利用所获得的2D坐标 将UI产生在设备萤幕的相对应位置上 *注意:y的坐标是要用设备萤幕的Height减去所获得的物件y坐标。

    结果示范:

    Unity3D教程:将3D坐标转成2D坐标的方法

    Unity3D教程:将3D坐标转成2D坐标的方法

    点中间的方块 UI就产生在中间 点左上的方块 UI就产生在左上

    应用:Tower Defense游戏中 点击画面中的物件 >然後卖出或升级

    展开全文
  • 学习Unity3D有两三天了,突然想起来该把自己学习的写出博客,方便以后复习。 那就从今天开始吧 今天遇到一个问题,在用Unity3D做2D游戏的动画播放器的时候(没有用第三方的插件)发现一个问题。 Unity3D的中1个...

    学习Unity3D有一段时间了,突然想起来该把自己学习的写出博客,方便以后复习。


    那就从今天开始吧


    今天遇到一个问题,在用Unity3D做2D游戏的动画播放器的时候(没有用第三方的插件)发现一个问题。

    Unity3D的中1个单位是一米,但我却不知道是多少像素


    举个例子,我有一张 400*300的 Texture,我新建了一个分辨率为800*600的工程

    并且在工程中创建了一个Plane用来保存Texture


    理论上来说,这个图像显示在屏幕上,应该是占用屏幕1/4的位置,长宽都为屏幕的一半才对


    但实际上,显示的大小与你的Plane的Tranform.Scale设置有关(默认为1,1,1)


    如果设置Scale,让它达到我们想要的效果。400的像素,我该设置Scale的值为多少?



    经过网上查找,解决办法如下


    设置Camera的Projection为Otrhgraphic

    并且设置Size为屏幕的一半(这里为300)


    接下来就简单了。

    把Plane的各个方向缩放图片大小的十分之一就可以了


    这个例子中,图片大小为400*300,那么设置为Scale(40, 1, 40)


    好了,问题解决了,虽然不是很完美,但做2D游戏,暂时可以了


    附上2D动画播放器的代码(代码啰嗦了一点)


    动画播放器的代码如下

    using UnityEngine;
    using System.Collections;
    
    public class AnimationManager : MonoBehaviour
    {
        public Material AnimationMaterial;
    
        public int RowFrameCount; // 每一行的帧数
        public int ColFrameCount; // 每一列的帧数
        public int TotalFrame; // 总帧数
    
        public int FrameWidth; // 每一帧的宽度
        public int FrameHeight;  // 每一帧的高度
    
        public int FPS; // 每秒播放的帧数
        public bool Loop = false; // 是否循环播放
    
        private int CurrRowFrame; // 当前帧的行
        private int CurrColFrame; // 当前帧的列
    
        private bool IsEnd; // 是否结束了
    
        private float elapsedTime; // 记录播放的时间
        private float frameTime; // 每一帧的时间(1 / fps)
    
    	void Start()
        {
            renderer.material = AnimationMaterial;
            
            renderer.material.SetTextureScale("_MainTex", new Vector2(1.0f / RowFrameCount, 1.0f / ColFrameCount));
            renderer.material.SetTextureOffset("_MainTex", new Vector2(0, 0));
    
            // 设置Camera的视图为正交矩阵,然后设置Size = Screen.Heigh / 2
            // 设置GameObject的Scale为Texture2D的十分之一即可
            transform.localScale = new Vector3(FrameWidth / 10, 1, FrameHeight / 10);
    
            CurrColFrame = 0;
            CurrRowFrame = 0;
    
            IsEnd = false;
    
            frameTime = 1.0f / FPS;
            elapsedTime = frameTime;
    
            if (TotalFrame == 0)
            {
                TotalFrame = RowFrameCount * ColFrameCount;
            }
    	}
    
    	void Update()
        {
            if (IsEnd)
            {
                return;
            }
    
            elapsedTime += Time.deltaTime;
    
            if (elapsedTime >= frameTime)
            {
                elapsedTime -= frameTime;
    
                CurrRowFrame++;
    
                if (CurrRowFrame + CurrColFrame * RowFrameCount >= TotalFrame)
                {
                    // 播放完成,如果循环
                    if (Loop)
                    {
                        CurrRowFrame = 0;
                        CurrColFrame = 0;
                    }
                    else
                    {
                        IsEnd = true;
                        return;
                    }
                }
    
                // 换行
                if (CurrRowFrame >= RowFrameCount)
                {
                    CurrRowFrame = 0;
    
                    CurrColFrame++;
    
                    if (CurrRowFrame + CurrColFrame * RowFrameCount >= TotalFrame)
                    {
                        // 播放完成,如果循环
                        if (Loop)
                        {
                            CurrRowFrame = 0;
                            CurrColFrame = 0;
                        }
                        else
                        {
                            IsEnd = true;
                            return;
                        }
                    }
    
                    // 换列
                    if (CurrColFrame >= ColFrameCount)
                    {
                        // 播放完成,如果循环
                        if (Loop)
                        {
                            CurrRowFrame = 0;
                            CurrColFrame = 0;
                        }
                        else
                        {
                            IsEnd = true;
                            return;
                        }
                    }
                }
    
                SetMaterialOffset();
            }
    	}
    
        private void SetMaterialOffset()
        {
            SetMaterialOffset(new Vector2(
                (float)CurrRowFrame * 1.0f / (float)RowFrameCount,
                (float)(ColFrameCount - 1 - CurrColFrame) * 1.0f / (float)ColFrameCount)); // 翻转纹理的坐标
        }
    
        private void SetMaterialOffset(Vector2 offset)
        {
            renderer.material.SetTextureOffset("_MainTex", offset);
        }
    }
    展开全文
  • Unity3D实战】零基础一步一步教你制作跑酷类游戏(填坑完整版) - Unity3D知识库

    一、前言

    最近跑酷游戏比较流行,开发教程也很多,但是大部分都是不太详细,这篇文章就带着大家一步一步开发出来一个跑酷类的游戏,教程比较基础,适合大部分Unity开发的初学者。
    还有就是,此专栏已经开通收费,里面整合的都是小游戏的开发教程,想要学习Unity开发游戏的,都可以订阅一下。
    如果文章出现什么问题,就及时联系我

    二、效果图&下载链接

    在这里插入图片描述
    Github地址:https://github.com/764424567/Game_Parkour

    三、教程

    在教程开始之前,我们分析一下跑酷类游戏制作思路。
    首先是道路和障碍物,我们可以先设置三段道路,然后障碍物随机生成
    道路中间有抵达点,角色到达抵达点判断是否将后面的道路移动到前面接起来。
    首先到达第一段的抵达点,肯定是不切换
    到达第二段的抵达点,将1号路段移动到最前面
    到达第三段的抵达点,将2号路段移动到最前面
    循环往复,无穷尽也
    然后是主角的移动脚本,躲避障碍物,移动位置固定三个点,可以跳,可以铲地
    主角碰到障碍物就挂,游戏结束

    1、新建项目

    博主的Unity版本是Unity5.6.1f1,推荐大家使用我这个版本,或者其他的5.6.x版本,不然可能会出现各种各样奇奇怪怪的问题。
    在这里插入图片描述
    文件目录的话就按照我这个目录来,比较清晰明了。

    2、导入资源

    资源已经上传到Github,需要的可以下载
    https://github.com/764424567/Unity-plugin/tree/master/ParkourDemo
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    3、处理动画资源

    在这里插入图片描述
    可以看到所有的动画文件都有。
    接着我们就可以新建一个Animator Controller文件来管理动画文件。
    在这里插入图片描述
    命名随意。
    在这里插入图片描述
    接着我们将动画剪辑拖到Animator处理面板中:
    在这里插入图片描述
    默认状态是run,然后有jump 、slide、idle
    在这里插入图片描述
    接着就是“Take Transition”将run和jump 以及 run 、slide、idle连下线。

    设置两个bool值,来控制动画的切换:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    接下来我们就可以在场景中看一下动画效果了:
    在这里插入图片描述

    4、处理路段模型

    在这里插入图片描述
    首先我们找到导入的资源SimpleRoadwork,里面有一个Demo场景,点进去可以看一下各类模型:
    在这里插入图片描述
    在Prefabs文件夹中,可以找到我们需要的各类模型,包括路面、路标、障碍物:
    在这里插入图片描述
    接下来,我们就设计一下路面:
    在这里插入图片描述
    在这里插入图片描述
    接着摆放路标:
    在这里插入图片描述
    接着摆放障碍物:
    在这里插入图片描述
    因为障碍物我们要后期自动生成,现在就可以先隐藏起来。
    在这里插入图片描述
    然后设置到达点(到达点的目的是当角色到达这个位置的时候,自动切换路线):
    在这里插入图片描述
    隐藏它的Mesh Renderer ,将BoxCollider IsTrigger设置成true:
    在这里插入图片描述
    路段就完成了:

    在这里插入图片描述
    整个目录如下:
    在这里插入图片描述
    不会摆放也没有关系,我已经设置好了,用我的也行。

    5、主角模型处理

    在这里插入图片描述

    明显是有点大,我们给它同比例缩小一下:
    在这里插入图片描述
    在这里插入图片描述
    接着设置一下摄像机的视角:

    在这里插入图片描述
    在这里插入图片描述

    6、生成障碍物

    新建脚本Control_Scenes.cs
    我们首先来生成障碍物:

    using UnityEngine;
    
    public class Control_Scenes : MonoBehaviour
    {
        public GameObject[] m_ObstacleArray;
        public Transform[] m_ObstaclePosArray;
    
        void Start()
        {
            Spawn_Obstacle(1);
        }
    	
    	//生成障碍物
    	public void Spawn_Obstacle(int index)
        {
            //销毁原来的对象
            GameObject[] obsPast = GameObject.FindGameObjectsWithTag("Obstacle" + index);
            for (int i = 0; i < obsPast.Length; i++)
            {
                Destroy(obsPast[i]);
            }
            //生成障碍物
            foreach (Transform item in m_ObstaclePosArray[index])
            {
                GameObject prefab = m_ObstacleArray[Random.Range(0, m_ObstacleArray.Length)];
                Vector3 eulerAngle = new Vector3(0, Random.Range(0, 360), 0);
                GameObject obj = Instantiate(prefab, item.position, Quaternion.Euler(eulerAngle));
                obj.tag = "Obstacle" + index;
            }
        }
    }
    
    

    将脚本挂在Control_Scenes对象上:
    将Prefab文件夹里面的模型拖入到ObstacleArray对象数组卡槽中
    将隐藏以后的障碍物拖入到ObstaclePosArray对象数组卡槽中
    在这里插入图片描述
    添加Tag:
    在这里插入图片描述
    运行看一下:
    在这里插入图片描述

    7、路段切换

    我们接着打开Control_Scenes.cs
    添加函数:

    void Start()
    {
            //Spawn_Obstacle(1);
            Change_Road(1);
    }
    public void Change_Road(int index)
    {
            if (m_ISFirst && index == 0)
            {
                m_ISFirst = false;
                return;
            }
            else
            {
                int lastIndex = index - 1;
                if (lastIndex < 0)
                    lastIndex = 2;
                m_RoadArray[lastIndex].transform.position = m_RoadArray[lastIndex].transform.position - new Vector3(150, 0, 0);
                Spawn_Obstacle(lastIndex);
            }
    }
    

    PS:这里解释一下代码,怎么切换的呢
    举个例子,角色跑到了第二段,那么第一段要移动到第三段后面隔一个路段长度的距离,接下来画个图:
    在这里插入图片描述
    那么为啥x轴减去150。这是因为我发现这三条路段的距离都差了50,坐标轴是负轴,所以就减去了150。
    在这里插入图片描述

    我们可以测试一下效果:
    在这里插入图片描述
    但是仅仅这样是不够的,我们还需要在角色到达抵达点的时候,切换路线,当然第一段路不用切换,因为再切就没了。。
    这个在我们写完角色移动以后再补充。

    8、角色移动

    新建脚本:Control_Player.cs
    说明一下:因为我们设定的三条道,所以角色只能在三条道里面切换。那么只需要改变角色的z值就可以了。如果角色在最左边,那么只能往右移动,同理在最右边,只能往左移动,在中间两边都可以移动。

    接着我们就可以看一下z轴的值:
    中间:
    在这里插入图片描述
    在这里插入图片描述

    左边:
    在这里插入图片描述
    在这里插入图片描述
    右边:
    在这里插入图片描述
    在这里插入图片描述
    代码:

    using UnityEngine;
    
    public class Control_Player : MonoBehaviour
    {
        //前进速度
        public float m_ForwardSpeeed = 7.0f;
        //动画组件
        private Animator m_Anim;
        //动画现在状态
        private AnimatorStateInfo m_CurrentBaseState;
    
        //动画状态参照
        static int m_jumpState = Animator.StringToHash("Base Layer.jump");
        static int m_slideState = Animator.StringToHash("Base Layer.slide");
    
        // Use this for initialization
        void Start()
        {
            m_Anim = GetComponent<Animator>();
        }
    
        // Update is called once per frame
        void Update()
        {
            transform.position += Vector3.left * m_ForwardSpeeed * Time.deltaTime;
            m_CurrentBaseState = m_Anim.GetCurrentAnimatorStateInfo(0);
            if (Input.GetKeyDown(KeyCode.W))
            {
                m_Anim.SetBool("jump", true);
            }
            else if (Input.GetKeyDown(KeyCode.S))
            {
                m_Anim.SetBool("slide", true);
            }
            else if (Input.GetKeyDown(KeyCode.A))
            {
                Change_PlayerZ(true);
            }
            else if (Input.GetKeyDown(KeyCode.D))
            {
                Change_PlayerZ(false);
            }
            if (m_CurrentBaseState.fullPathHash == m_jumpState)
            {
                m_Anim.SetBool("jump", false);
            }
            else if (m_CurrentBaseState.fullPathHash == m_slideState)
            {
                m_Anim.SetBool("slide", false);
            }
        }
    
        public void Change_PlayerZ(bool IsAD)
        {
            if (IsAD)
            {
                if (transform.position.z == -14.7f)
                    return;
                else if (transform.position.z == -9.69f)
                {
                    transform.position = new Vector3(transform.position.x, transform.position.y, -14.7f);
                }
                else
                {
                    transform.position = new Vector3(transform.position.x, transform.position.y, -9.69f);
                }
            }
            else
            {
                if (transform.position.z == -6.2f)
                    return;
                else if (transform.position.z == -9.69f)
                {
                    transform.position = new Vector3(transform.position.x, transform.position.y, -6.2f);
                }
                else
                {
                    transform.position = new Vector3(transform.position.x, transform.position.y, -9.69f);
                }
    
            }
        }
    }
    
    

    键盘WSAD控制上跳,下滑,左右移动等操作。现在就可以去试试啦。
    在这里插入图片描述

    但是,有一点哈,角色怎么越跑越远离开了我们呢,因为,还没有写摄像机跟随脚本,接下来继续吧。

    9、摄像机跟随

    新建脚本Control_Camera.cs

    using UnityEngine;
    
    public class Control_Camera : MonoBehaviour
    {
    	//间隔距离
    	public float m_DistanceAway = 5f;
    	//间隔高度
    	public float m_DistanceHeight = 10f;
    	//平滑值
    	public float smooth = 2f;               
    	//目标点
    	private Vector3 m_TargetPosition;      
    	//参照点
    	Transform m_Follow;        
    
    	void Start()
    	{
    		m_Follow = GameObject.Find("Player").transform;
    	}
    
    	void LateUpdate()
    	{
    		m_TargetPosition = m_Follow.position + Vector3.up * m_DistanceHeight - m_Follow.forward * m_DistanceAway;
    		transform.position = Vector3.Lerp(transform.position, m_TargetPosition, Time.deltaTime * smooth);
    	}
    }
    
    

    OK 摄像机跟着Player跑起来了

    10、碰撞检测

    我们需要不停的躲避障碍物,一旦碰撞到障碍物就dead了
    我们首先修改障碍物的碰撞器属性:
    在这里插入图片描述
    Mesh Collider : Is Trigger=true
    在这里插入图片描述
    我们给Player加上刚体和碰撞体:
    在这里插入图片描述
    注意要勾上Is Trigger

    打开Control_Player.cs脚本:

    //游戏结束
    bool m_IsEnd = false;
    void OnGUI()
    {
            if (m_IsEnd)
            {
                GUIStyle style = new GUIStyle();
                style.alignment = TextAnchor.MiddleCenter;
                style.fontSize = 40;
                style.normal.textColor = Color.red;
                GUI.Label(new Rect(Screen.width / 2 - 100, Screen.height / 2 - 50, 200, 100), "你输了~", style);
            }
    }
    void OnTriggerEnter(Collider other)
        {
            if (other.gameObject.name == "Vehicle_DumpTruck" || other.gameObject.name == "Vehicle_MixerTruck")
            {
                m_IsEnd = true;
                m_ForwardSpeeed = 0;
                m_Anim.SetBool("idle", true);
            }
        }
    

    11、切换道路

    在第七章的时候就已经写好了道路切换,但是一直没有讲到碰撞检测,那么现在我们就结合碰撞检测,检测到抵达点然后切换道路吧

    我们首先找到三个抵达点:MonitorPos
    然后改名叫做MonitorPos0 MonitorPos1 MonitorPos2
    在这里插入图片描述
    修改一下BoxCollider的Is Trigger属性:
    在这里插入图片描述
    修改Control_Player.cs的代码:

     //场景控制对象
    Control_Scenes m_ControlScenes;
    void Start()
    {
            m_Anim = GetComponent<Animator>();
            m_ControlScenes = GameObject.Find("Control_Scenes").GetComponent<Control_Scenes>();
    }
    void OnTriggerEnter(Collider other)
    {
            if (other.gameObject.name == "Vehicle_DumpTruck" || other.gameObject.name == "Vehicle_MixerTruck")
            {
                m_IsEnd = true;
                m_ForwardSpeeed = 0;
                m_Anim.SetBool("idle", true);
            }
            if (other.gameObject.name == "MonitorPos0")
            {
                m_ControlScenes.Change_Road(0);
            }
            else if (other.gameObject.name == "MonitorPos1")
            {
                m_ControlScenes.Change_Road(1);
            }
            else if (other.gameObject.name == "MonitorPos2")
            {
                m_ControlScenes.Change_Road(2);
            }
    }
    
    展开全文
  • Live2d Unity插件

    2020-06-03 23:31:18
    Live2d Unity插件最新版本,保护完整插件和例子,非常好
  • Unity3D中引用Spine2D动画研究学习(一) Spine2D是一款针对游戏制作2D骨骼动画的编工具,与传统的帧动画相比,有以下特点: 由于本人是Unity程序员,关注点在于如何在Unity工具中使用控制Spine导出的...
    Unity3D中引用Spine2D动画研究学习(一)
    Spine2D是一款针对游戏制作2D骨骼动画的编工具,与传统的帧动画相比,有以下特点:


    由于本人是Unity程序员,关注点在于如何在Unity工具中使用控制Spine导出的动画数据。接下来主要介绍关于上述的问题!
    (1)从Spine2D中导出已做好的动画数据:Unity中支持JSON格式数据,因此将动画导出为JSON格式,并且勾选上Pretty print 和 Create atlas 2个选项

    最后产生3份文件:

    a.spineboy.atlas文件记录了对象模型的各个组成部分在图集中的位置信息;另外值得注意的是:该文件导入Unity之前,再加上一后缀.txt文件,因为目前Unity目前只能识别.txt文件。

    b.spineboy JSON File文件记录了该对象的各种动作数据信息;

    c.spineboy PNG 类似于NGUI的精灵图集一样


    (2)将支持Spine2D的动画的运行库导入Unity工程中,关于该资源文件可以到GitHub上获取,链接:https://github.com/EsotericSoftware/spine-runtimes/tree/master/spine-unity 这里有2种方式获取和导入它,一种是直接下载 Spine_Unity.unitypackage资源,像平常Unity添加插件资源一样导入;第二种方式下载其压缩包,将其中spine-csharp和spine-unity文件拷入Unity工程中。下面是我使用第1种方式导入Unity工程中目录结构,它里面包含了一些例子。


    (3)将上面从Spine2D导出的3份文件,拖入工程中,此时会产生另外2个相应材质和图集资源.asset文件


    (4)要想使用Spine动画数据,还需要创建SkeletonData文件,右键选择“SkeletonData”进行创建。主要设置2个参数:Atlas Assets (图集资源)和 Skeleton JSON(动画数据信息)


    (5)这样,就可以开始在Unity场景中,创建SkeletonAnimation组件对象了!选择“GameObject”--"Create Other"--"SkeletonAniamtionm"


    如此,目前已经把Spine2D制作的动画成功地在Unity中应用。至于,如何通过脚本编写来控制Spine2D动画,以后再与大家交流分享,本人也在学习当中。

    展开全文
  • 各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.csdn.net/...比如博主在写《[Unity3D]Unity3D游戏开发之自由视角下的角色控制》和《[Unity3D]Unity3D游戏开发之角色控制漫谈》这两篇

            各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei。今天我们来做点简单的东西,做个什么呢?答案就是截屏。作为一名热爱单机游戏的玩家,博主每次在玩游戏的同时截取游戏中比较喜欢的画面,特别是学习了Unity3D以后玩游戏的时候更多地是从一个游戏设计者的角度来看待游戏,换句话说,可能关注技术的成分更多一点吧。比如博主在写[Unity3D]Unity3D游戏开发之自由视角下的角色控制》[Unity3D]Unity3D游戏开发之角色控制漫谈》这两篇文章时,碰到博主无法把握的问题的时候就是通过玩游戏来体会的,在玩游戏的过程中博主总是会抓取博主比较喜欢的画面,如图,下面是博主收集的部分截图:




           好了,欣赏完美丽的风景,下面我们就来一起学习在Unity3D实现截屏,先给出实现截屏的三种实现方式:

    /// <summary>
    	/// 使用Application类下的CaptureScreenshot()方法实现截图
    	/// 优点:简单,可以快速地截取某一帧的画面、全屏截图
    	/// 缺点:不能针对摄像机截图,无法进行局部截图
    	/// </summary>
    	/// <param name="mFileName">M file name.</param>
    	private void CaptureByUnity(string mFileName)
    	{
    		Application.CaptureScreenshot(mFileName,0);
    	}
    
    	/// <summary>
    	/// 根据一个Rect类型来截取指定范围的屏幕
    	/// 左下角为(0,0)
    	/// </summary>
    	/// <param name="mRect">M rect.</param>
    	/// <param name="mFileName">M file name.</param>
    	private IEnumerator CaptureByRect(Rect mRect,string mFileName)
    	{
    		//等待渲染线程结束
    		yield return new WaitForEndOfFrame();
    		//初始化Texture2D
    		Texture2D mTexture=new Texture2D((int)mRect.width,(int)mRect.height,TextureFormat.RGB24,false);
    		//读取屏幕像素信息并存储为纹理数据
    		mTexture.ReadPixels(mRect,0,0);
    		//应用
    		mTexture.Apply();
    		
    		
    		//将图片信息编码为字节信息
    		byte[] bytes = mTexture.EncodeToPNG();  
    		//保存
    		System.IO.File.WriteAllBytes(mFileName, bytes);
    		
    		//如果需要可以返回截图
    		//return mTexture;
    	}
    
    	private IEnumerator  CaptureByCamera(Camera mCamera,Rect mRect,string mFileName)
    	{
    		//等待渲染线程结束
    		yield return new WaitForEndOfFrame();
    
    		//初始化RenderTexture
    		RenderTexture mRender=new RenderTexture((int)mRect.width,(int)mRect.height,0);
    		//设置相机的渲染目标
    		mCamera.targetTexture=mRender;
    		//开始渲染
    		mCamera.Render();
    		
    		//激活渲染贴图读取信息
    		RenderTexture.active=mRender;
    		
    		Texture2D mTexture=new Texture2D((int)mRect.width,(int)mRect.height,TextureFormat.RGB24,false);
    		//读取屏幕像素信息并存储为纹理数据
    		mTexture.ReadPixels(mRect,0,0);
    		//应用
    		mTexture.Apply();
    		
    		//释放相机,销毁渲染贴图
    		mCamera.targetTexture = null;   
    		RenderTexture.active = null; 
    		GameObject.Destroy(mRender);  
    		
    		//将图片信息编码为字节信息
    		byte[] bytes = mTexture.EncodeToPNG();  
    		//保存
    		System.IO.File.WriteAllBytes(mFileName,bytes);
    		
    		//如果需要可以返回截图
    		//return mTexture;
    	}
    
    }
    

          接下来,我们来调用这三个方法实现一个简单的截图的例子:

    //定义图片保存路径
    	private string mPath1;
    	private string mPath2;
    	private string mPath3;
    
    	//相机
    	public Transform CameraTrans;
    
    	void Start()
    	{
    		//初始化路径
    		mPath1=Application.dataPath+"\\ScreenShot\\ScreenShot1.png";
    		mPath2=Application.dataPath+"\\ScreenShot\\ScreenShot2.png";
    		mPath3=Application.dataPath+"\\ScreenShot\\ScreenShot3.png";
    	}
    
    	//主方法,使用UGUI实现
    	void OnGUI()
    	{
    		if(GUILayout.Button("截图方式1",GUILayout.Height(30))){
    			CaptureByUnity(mPath1);
    		}
    		if(GUILayout.Button("截图方式2",GUILayout.Height(30))){
    			StartCoroutine(CaptureByRect(new Rect(0,0,1024,768),mPath2));
    		}
    		if(GUILayout.Button("截图方式3",GUILayout.Height(30))){
    			//启用顶视图相机
    			CameraTrans.camera.enabled=true;
    			//禁用主相机
    			Camera.main.enabled=false;
    			StartCoroutine(CaptureByCamera(CameraTrans.camera,new Rect(0,0,1024,768),mPath3));
    		}
    	}
    
    
    	
           在第三中截图方式中,博主在场景里放了一个名为TopCamera的摄像机,它垂直向下投影到游戏场景里,这样可以使玩家看到场景的顶视图。这里我们用这个相机来测试第三个方法,此时需要先激活该相机。场景设置如图:


            我们下面来看三种方法截图的效果:





            从截图的效果来看,第一种方法的效果是最好的,不过定制化是个问题。第二种方法效果一般吧,感觉这里TextureFormat没有选好吧。第三种效果基本达到了博主想要的要求,不过摄像机的投影范围似乎没有设计好。这里我们发现第二张截图会把编辑器的窗口渲染到里面,博主认为是程序运行的时候,即使将Game窗口放到最大,仍然会受到窗口的影响,后来博主就把程序编译成可执行文件,不过程序运行完之后,博主却没有找到对应的截图。后来查找了官方的API才知道原因是这样的:

    Description

    Contains the path to the game data folder (Read Only).

    The value depends on which platform you are running on:

    Unity Editor: <path to project folder>/Assets

    Mac player: <path to player app bundle>/Contents

    iPhone player: <path to player app bundle>/<AppName.app>/Data

    Win player: <path to executablename_Data folder>

    Web player: The absolute url to the player data file folder (without the actual data file name)

    Flash: The absolute url to the player data file folder (without the actual data file name)

    Note that the string returned on a PC will use a forward slash as a folder separator
     

            显然,我们从这里可以知道Application.datapath在不同的平台上对应的位置。对于可执行(.exe,Windows平台)的文件,它对应在和应用程序对应的一个文件夹里,例如可执行文件的名字叫做UnityGame,那么对应的位置就是UnityGame_Data这个文件啦。所以博主的问题应该是出在没有在这里建一个ScreenShot的文件夹,希望大家以后做相关项目的时候注意一下吧。好了,这就是今天的内容了,希望大家喜欢啊。


    每日箴言:无所谓好或不好,人生一场虚空大梦,韶华白首,不过转瞬。惟有天道恒
    在,往复循环,不曾更改——慕容紫英。




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




    展开全文
  • 什么是Live2D Live2D是日本Cybernoids公司开发。 Live2D现阶段有两个主要的版本是2.1的版本和3.0的版本。 国内2.1版本用的比较多(ps.此为自己的感觉,并没有数据支持,只是感觉国内讨论的比较多的就是2.1了)。 ...
  • 大家晚上好,我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.csdn.net/...所以,今天的博客的主题就是《Unity3D游戏开发之跑酷游戏项目讲解》。从博主自身来考虑这件事情,当你选择做自己热爱的事情的时
  • unity3d 各大插件评测

    2018-01-30 15:00:43
    原创文章如需转载请注明:转载自风宇冲Unity3D教程学院 引言:想用Unity3D制作优秀的游戏,插件是必不可少的。工欲善其事必先利其器。本文主旨是告诉使用Unity3D引擎的同学们如何根据需求选择适当的工具...
  • 教程基于http://pixelnest.io/tutorials/2d-game-unity/, 这个例子感觉还是比较经典的, 网上转载的也比较多. 刚好最近也在学习U3D, 做的过程中自己又修改了一些地方, 写篇文和大家一起分享下, 同时也加深记忆. 有...
  • Unity3D 模型换肤技术

    2015-12-10 15:42:39
    最近在看Unity3D的人物模型和动画。所以今天先说下人物的换装吧。相信大家都玩过网游吧,没有玩过的也相信见过,就是网游或者单机游戏里的人物会有更换服装,更换武器的功能。如果外形(mesh)是一样的,那么把贴图换...
  • 原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 QQ群:【Unity3D(AR/VR) 334163814】【Unity3D(游戏) 119706192】 本文链接地址: Unity3D 一些基础的方向、距离算法 最近做一款一款3D“跑酷”游戏终于要...
  • 笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。 CSDN视频网址...
  • 大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei。 在《仙剑奇侠传》、《古剑奇谭》等游戏中...那么,这一功能如何在Unity3D中实现呢?首先我们可以将问题分解为两个子问题:第一
  • Unity3d不久之前正式发布了Unity3d 2017.1, 这个版本的发布也宣告了Unity3d正式告别了5.x时代,并且开始已年份直接命名,开启了新的纪元。那么Unity3d 2017相较上一版本到底有哪些改进呢?这介绍这些改进之前先放出...
  • 我是从cocos2d 转移阵营过来的 unity下开发2d游戏真是不习惯。。。特别是2d中有许多特性是非常必要的,但是unity本身又支持得非常烂的...所以这时候就要用过第3方插件,我试过EZGUI, sm2,gm2,还有一个忘了名字的2d...
  •  在这里笔者用一个项目中的例子,即将摄像头捕获的人体关节点坐标json数据解析出来,再让Unity中的模型关节依次移动到相应位置的过程。 详情见全文 (2) 问题分析: 需要解析的json数据如图所示:  由于只需搭建...
  • 一个课程项目,用Unity3D写雷电游戏,感觉有点大材小用。用3D的引擎来写一个2D小游戏,不过会方便许多,可以方便的添加三维的逻辑,比如有地面上的攻击单位,你却打不到它,也可以让飞机从地面升空之类的。 国内...
  • Unity3D常见面试题

    2017-08-11 20:20:00
    Unity3D常见面试题
  • 2d animation https://docs.unity3d.com/Packages/com.unity.2d.animation@3.1/manual/index.html 2d场景的光照效果 https://www.youtube.com/watch?v=F5l8vP90EvU
1 2 3 4 5 ... 20
收藏数 3,904
精华内容 1,561
热门标签
关键字:

2d例子 unity3d