2017-08-25 00:23:57 biezhihua 阅读数 4264
  • Unity3D入门到精通-(3)Unity资源管理精讲

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

    4645 人正在学习 去看看 张刚

3D坐标系是3D游戏开发的基础概念。一般3D软件都是采用笛卡尔坐标系来描述物体的坐标信息。笛卡尔坐标系分为左手坐标系和右手坐标系:

  • 左手坐标系是Y轴指向上方,X轴指向右方,Z轴指向前方。
  • 右手坐标系是Y轴指向上方,X轴指向右方,Z轴指向后方。

这里写图片描述

在Unity中使用的是左手坐标系,其中X轴代表水平方向,Y轴代表垂直方向,而Z轴代表深度。

Unity有如下几种坐标系统。

1,全局坐标系(world coordinate system)

全局坐标系是用于描述场景内所有物体位置和方向的基准,也称为世界坐标系(也就是上面提到的笛卡尔左手坐标系)。

在Unity场景中创建的物体都是以全局坐标系中的坐标原点(0,0,0)来确定各自的位置。

2,局部坐标系(local coordinate system)

每个物体都有其独立的物体坐标系,并且随物体进行相同的移动或旋转,也称为模型坐标系或物体坐标系。

通过点击工具栏中的GlobalLocal,可以清楚的看到物体的局部坐标系与全局坐标系的不同。

如果一个物体有父物体,那么父子之间的坐标系是相互关联的,此时子物体会以父物体作为自身局部坐标系的坐标原点。

3,相机坐标系

以摄像机视角出发,观察物体的位置和方向建立的坐标系。使用此坐标系可以方便的判断物体是否在相机前方以及物体之间的先后遮挡顺序。

4,屏幕坐标系

建立在屏幕上的二维坐标系,用来描述像素在屏幕上的位置。

说道3D坐标系就必须提到Transform,Transform表示一个物体的位置、旋转、缩放等信息。

1,位置(position/localPosition)

先阐述两个最基本的概念:

  • transform.position:表示该物体在全局坐标中的位置信息。
  • transform.localPosition:表示该物体相对于父物体的位置信息。

最普通的方法Transform.Translate,可以将自身在某个方向上移动某段距离,方向(direction)和距离(distance)由第一个参数(translation)指定。于是我们可以看到如下的代码:

public class ExampleClass : MonoBehaviour {
    void Update() {
        // 将自身(局部坐标系)在前方(Z轴)移动(1*一帧的持续时间)的距离
        transform.Translate(Vector3.forward * Time.deltaTime);
    }
}

Translate方法还有第二个参数Space可供选择,Space表示使用的坐标空间(全局、局部),于是就会有如下代码:

public class ExampleClass : MonoBehaviour {
    void Update() {
        // 将自身(全局坐标系)在上方(Y轴)移动(1*一帧的持续时间)的距离
        transform.Translate(Vector3.up * Time.deltaTime, Space.World);
    }
}

该段代码与段代码最重要的不同在于,前者应用Translate到局部坐标系,而后者应用Translate到全局坐标系,源码可以清晰的表现出这段关系:

/// <summary>
///   <para>Moves the transform in the direction and distance of translation.</para>
/// </summary>
/// <param name="translation"></param>
/// <param name="relativeTo"></param>
public void Translate(Vector3 translation, [DefaultValue("Space.Self")] Space relativeTo)
{
  if (relativeTo == Space.World)
    this.position += translation;
  else
    this.position += this.TransformDirection(translation);
}

// 如果没有第二个参数或参数为Space.Self,那么先将`translation`由局部坐标系转为全局坐标系,再与自身`position`相加。
// 如果第二个参数为Space.World,那么直接与自身`position`相加。

在Unity中,Transform组件的Transform.TransformPoint方法可以将坐标点从局部坐标系转换到全局坐标系,Transform.InverseTransformPoint可以将坐标点从全局坐标系转换到局部坐标系。而Transform.TransformDirectionTransform.InverseTransformDirection则用于对向量在局部坐标系和全局坐标系之间进行转换。

根据上述,下面两段代码效果是相同的:

// 先将方向从全局坐标系转换到局部坐标系,再通过Translate内部调用TransformDirection方法将方向从局部坐标系转换为全局坐标系,最后加到自身的position上。
Vector3 up = transform.InverseTransformDirection(Vector3.up);
transform.Translate(up * Time.deltaTime, Space.Self);

// 直接将translation加到自身的position上。
transform.Translate(Vector3.up * Time.deltaTime, Space.World);

Transform源码在这里

2,旋转(rotate/localRotate)

由于和位置很类似就不赘述了。

2016-01-07 17:30:07 newbieol 阅读数 862
  • Unity3D入门到精通-(3)Unity资源管理精讲

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

    4645 人正在学习 去看看 张刚

在Unity3D游戏开发过程中,UI界面表现有着举足轻重的地位,好的表现效果能让游戏增色不少。要让 UI 精灵图片有独特的表现效果,需要给图片加上特定的 Shader 着色器,这样一来就能让这个图片表现出独特的效果,比如:溶解、消失等等。

然而在Unity3D游戏开发中因为精灵被打包到图集里面,运行起来的效果大相径庭,Shader 里面 uv 坐标不再是单个图片的坐标了,而是图集里面该图片的坐标,使得 Shader 计算错误,最终渲染错乱。

今天我们就先来介绍下简单的处理 Alpha 融合方法,具体代码如下:

using UnityEngine;

using UnityEngine.UI;

public class VertIndexAsUV1 : BaseMeshEffect

{

public override void ModifyMesh(VertexHelper vh)

{

if (!IsActive())

return;

UIVertex vert = new UIVertex();

for (int i = 0; i < vh.currentVertCount; i++)

{

vh.PopulateUIVertex(ref vert, i);

vert.uv1.x = (i >> 1);

vert.uv1.y = ((i >> 1) ^ (i & 1));

vh.SetUIVertex(vert, i);

}

}

}

今天的知识点总结就先到这里,若还有不明白的欢迎到菜鸟在线观看Unity3D游戏开发课程,也可留言。每次的分享都是根据大家的留言总结的,所以想知道什么就得积极互动哦!

2015-03-08 18:18:50 book_longssl 阅读数 722
  • Unity3D入门到精通-(3)Unity资源管理精讲

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

    4645 人正在学习 去看看 张刚

参考坐标系(Reference Coordinate System)列表是让你指定用于变换(移动move、旋转rotate和缩放scale)的坐标系。选项包括视图坐标view,屏幕坐标screen,世界坐标world,父坐标parent,局部坐标local,网格坐标grid和拾取坐标pick。

在屏幕坐标系下,所有的视图(包括***图perspective)使用视口屏幕坐标。 视图坐标view是世界坐标world和屏幕坐标screen的混合坐标系。使用视图坐标时,所有的正交视图(orthgraphic views)使用屏幕坐标screen,然而***图使用世界坐标world。

注意:坐标系被设置在一种变换对另一种变换的基础之上,所以在选择坐标系之前应先选择变化方式。如果你不想改变坐标系,打开Customize menu > Preferences > General tab > Reference Coordinate System group > Constant。
逐项解释:
View视图坐标:在默认坐标系下,在所有的(正交)视图中X,Y,Z三个轴是相同的。当你使用这个坐标系移动一个对象时,你所移动的对象与视口空间有如下关系。

·X轴总是指向(屏幕)右侧。
·Y轴总是指向(屏幕)上方。
·Z轴总是垂直屏幕指向你。
Screen屏幕坐标:使用激活的视口屏幕作为坐标系。
·X轴是水平的,正方向指向(屏幕)右侧。
·Y轴是垂直的,正方向指向(屏幕)上方。
·Z轴是进深的,正方向指向你。

因为屏幕坐标模式是以激活视口作为它的坐标方向,未激活视口中轴三脚架上X,Y,Z的指向显示当前激活视口的方向。当你激活这个视口时,轴三脚架上的指向将会改变。

World世界坐标:从前视图front看:
·X轴正方向指向(屏幕)右侧。
·Z轴正方向指向(屏幕)上方。
·Y轴正方向背离你。
Parent父坐标:使用所选择对象的父对象的坐标系统。如果对象未链接到特定的物体上,那么它是世界的子物体,即父坐标与世界坐标相同。
Local局部坐标:使用所选择对象的坐标系统。一个对象的局部坐标来自它的枢轴点。你可以通过使用选项中的Hierarchy命令面板, 相对于对象调整局部坐标的位置和方向。
当局部坐标处于激活状态,按钮“Use Transform Center”是不起作用的,所用的变换使用局部坐标轴作为变换的中心。在一个选择集中的几个物体,每个分别使用它自己的中心来做变换。
Grid网格坐标:使用激活网格的坐标系。
Pick拾取坐标:使用场景中另一个对象的坐标系。
当你选择Pick以后,单击选择单个物体,此物体的坐标系将被用于变换。对象的名字出现在变换坐标系列表中。
事实是在列表中所存储的对象名称使你可以拾取此对象的坐标系,改变激活的坐标系,而且可以稍后再使用对象坐标系。列表中储存四个最近拾取的对象名称。
当你使用拾取坐标来指定一个对象作为参考坐标系时,你能够按下“H”显示选择对象对话框,并从那里选择对象。

----World Coordinate System--世界坐标系
这个坐标系将世界空间或模型空间作为一个整体。
世界空间是世界坐标系,世界坐标系是软件用于在场景中追踪对象的。当你看到视口中的主珊格,你就见到世界空间坐标系。世界空间是固定不变的。
在世界坐标系下,从前视图front看去,X轴正方向指向(屏幕)右侧,Z轴正方向指向(屏幕)上方,Y轴正方向背离你。

----Local Coordinate System--局部坐标系 局部坐标系是与所选择对象具有特定关系的坐标系。
每个对象有它自己的局部中心和坐标系,这与定义的此对象枢轴点的位置和方向相同。一个对象的局部中心和坐标系联合定义了它的物体空间。
对象的X,Y,Z轴的方向,Z轴依赖于对象的当前变换。与世界坐标系比较。当你无意中旋转一个对象时你能够发现两个坐标系之间的不同,例如一个汽车模型的车轮,用世界坐标轴代替对象局部坐标轴。车轮立即沿一个大的弧线飞出,因为旋转的中心是在世界坐标的原点。
要正确旋转车轮,首先变换坐标系为局部坐标,使用工具条中的参考坐标系列表。车轮绕它自己的中心旋转,那里是他局部坐标的原点。

----Pivot Point--枢轴点
变换中心,或称枢轴点,是发生旋转或发生比例变形的部位。
所有的物体具有一个枢轴点。你可以想象枢轴点为一个对象的局部中心或局部坐标系的代表。
一个对象的枢轴点用于以下几个目的:
·当枢轴点变换中心被选择时,作为旋转和比例变换的中心。
·设置修改器中心的默认位置。
·定义所链接子物体的变换原点。
·定义IK结合的位置。

通过使用“Hierarchy”命令面板中的“Pivot”功能,你能够在任何时候显示和调节一个对象的枢轴点的位置和方向,调节一个对象的枢轴点不会影响任何与其链接的子物体。



2019-10-26 18:00:08 qq_39339846 阅读数 45
  • Unity3D入门到精通-(3)Unity资源管理精讲

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

    4645 人正在学习 去看看 张刚

【Unity3D】世界坐标转屏幕坐标的坑

本菜鸟是今年2019年毕业,正式走向游戏开发岗位三个月的大萌新。每天忙着和策划各种撕逼,实现各种脑残设计,其中就遇到不少值得罗缕纪存的坑,现在就开始写下了供后来的学习者跳坑。
策划之前提了一个玩家目标指示器需求,箭头始终指向玩家点击的目标在屏幕上的位置。接到需求第一个想法是直接将目标单位的世界坐标转换成ugui的屏幕坐标,使用unity自带的坐标转换函数转换就行了。
ugui以左下角为坐标原点(0,0),向上为y轴正半轴,向右为x轴正半轴。所以先计算目标的屏幕坐标和玩家摄像机屏幕中心坐标的两点之间的角度angle,通过判断目标屏幕坐标相对于摄像机屏幕中心位于哪个象限,处理之前计算的angle差值(ugui图片的角度是逆时针从0到360)。

//将目标世界坐标转换成ugui屏幕坐标
Vector3 target_ScreenPoint = Camera.main.WorldToScreenPoint(m_target.position);
//计算target_ScreenPoint和屏幕中心点的绝对值角度

float angle = Mathf.Atan(Mathf.Abs(target_ScreenPoint.y - Screen.height / 2)
    / Mathf.Abs(target_ScreenPoint.x - Screen.width / 2)) * 180 / Mathf.PI;

//通过判断target_ScreenPoint相对屏幕中心点所在象限处理angle的差值
if (target_ScreenPoint.x <= Screen.width / 2)
    angle = target_ScreenPoint.y >= Screen.height / 2 ? 90 - angle : 90 + angle;
else
    angle = target_ScreenPoint.y >= Screen.height / 2 ? 270 + angle : 270 - angle;

Vector3 euler = m_arrow.eulerAngles;
euler.z = angle;
//设置箭头的角度
m_arrow.eulerAngles = euler;

下面是效果图

在这里插入图片描述
箭头指示器始终指向目标在屏幕显示的位置,是不是很完美无缺。但狗策划测试发现个问题,当目标不在屏幕内,玩家转动到某些角度时候,箭头指示器会指向相反方向。如下图所示

在这里插入图片描述
此时目标不在屏幕范围内,在人物左边,转换成的屏幕坐标x值为负也正常,但当人物继续向右转动后出现下图问题了。
在这里插入图片描述
指向箭头刚才还指向左边,现在指向右边相反方向了,目标转换成的屏幕左边x值也变成正的了,所以这时候需要把箭头角度改成对角相反的方向。至于什么时候改了,需要通过判断当目标在摄像头左边但指示箭头角度大于180度和当目标在摄像头右边但指示箭头角度小于180时候转换即可,最后达到了真正完美的效果图如下。

在这里插入图片描述
这回即使旋转一周箭头位置都没任何问题,最后上完整代码

using UnityEngine;

public class GuideUICtl : MonoBehaviour
{
    public Transform m_target;                  //指向目标
    public RectTransform m_arrow;               //UI箭头
    Vector3 m_Screen_Center;

    private void Start()
    {
        m_Screen_Center = new Vector3(Screen.width / 2, Screen.height / 2, 0);
    }
    
    void Update() {
        //将目标的世界坐标转换成屏幕坐标
        Vector3 target_ScreenPoint = Camera.main.WorldToScreenPoint(m_target.position);

        //计算target_ScreenPoint和屏幕中心点的绝对值角度
        float angle = Mathf.Atan(Mathf.Abs(target_ScreenPoint.y - Screen.height / 2)
            / Mathf.Abs(target_ScreenPoint.x - Screen.width / 2)) * 180 / Mathf.PI;

        //通过判断target_ScreenPoint相对屏幕中心点所在象限处理angle的差值
        if (target_ScreenPoint.x <= Screen.width / 2)
            angle = target_ScreenPoint.y >= Screen.height / 2 ? 90 - angle : 90 + angle;
        else
            angle = target_ScreenPoint.y >= Screen.height / 2 ? 270 + angle : 270 - angle;

        #region  计算摄像机和目标的叉乘

        //以屏幕中心所在的单位向量为起始向量from,并将from的y值设成和目标y值保持一致
        Vector3 from = Camera.main.transform.forward;
        from.y = m_target.forward.y;
        //将屏幕中心坐标转换成世界坐标
        Vector3 cameraPos = Camera.main.ScreenToWorldPoint(m_Screen_Center);
        cameraPos.y = m_target.position.y;
        
        //求出目标点与摄像机之间的向量
        Vector3 to = m_target.position - cameraPos;
        //求出两向量之间的叉乘
        Vector3 cross = Vector3.Cross(from, to);
        #endregion

        //根据叉乘求出带符号的角度
        //cross.y > 0:目标向量位于起始向量右侧
        //cross.y < 0:目标向量位于起始向量左侧
        if (cross.y > 0 && angle < 180)
            angle += 180;
        else if (cross.y < 0 && angle > 180)
            angle -= 180;
        Vector3 euler = m_arrow.eulerAngles;
        euler.z = angle;
        
        //设置箭头的角度
        m_arrow.eulerAngles = euler;
    }
}

2015-03-30 15:29:19 book_bigthumb 阅读数 289
  • Unity3D入门到精通-(3)Unity资源管理精讲

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

    4645 人正在学习 去看看 张刚
Unity3D的四种坐标系
1、World Space(世界坐标):我们在场景中添加物体(如:Cube),他们都是以世界坐标显示在场景中的。transform.position可以获得该位置坐标。

2、Screen Space(屏幕坐标):以像素来定义的,以屏幕的左下角为(0,0)点,右上角为(Screen.width,Screen.height),Z的位置是以相机的世界单位来衡量的。注:鼠标位置坐标属于屏幕坐标,Input.mousePosition可以获得该位置坐标,手指触摸屏幕也为屏幕坐标,Input.GetTouch(0).position可以获得单个手指触摸屏幕坐标。
  Screen.width = Camera.pixelWidth
  Screen.height = Camera.pixelHeigth
3、ViewPort Space(视口坐标):视口坐标是标准的和相对于相机的。相机的左下角为(0,0)点,右上角为(1,1)点,Z的位置是以相机的世界单位来衡量的。

4、绘制GUI界面的坐标系:这个坐标系与屏幕坐标系相似,不同的是该坐标系以屏幕的左上角为(0,0)点,右下角为(Screen.width,Screen.height)

四种坐标系的转换
1、世界坐标→屏幕坐标:camera.WorldToScreenPoint(transform.position);这样可以将世界坐标转换为屏幕坐标。其中camera为场景中的camera对象。

2、屏幕坐标→视口坐标:camera.ScreenToViewportPoint(Input.GetTouch(0).position);这样可以将屏幕坐标转换为视口坐标。其中camera为场景中的camera对象。

3、视口坐标→屏幕坐标:camera.ViewportToScreenPoint();

4、视口坐标→世界坐标:camera.ViewportToWorldPoint();

声明:此篇文档时来自于【狗刨学习网】社区,是网友自行发布的Unity3D学习文章,如果有什么内容侵犯了你的相关权益,请与官方沟通,我们会即时处理。
没有更多推荐了,返回首页