Unity2D
相机调整:Projection设置为Orthographic。也就是正交模式,忽视距离。
资源:
Sprite:一种游戏资源,在2D游戏中表示角色场景的图片资源
SpriteSheet:切割一张图片为多个Sprite
在Sprite Editor中可以切割图片,要在Package Manager中下载2D Sprite包。
图片可以更改中心点(拖动中间的圆圈),也可以设置Custom Pivot。这决定了图片怎么显示。
SpriteRenderer组件参数设置:
Sprite:设置图片
Color:给图片叠加颜色
Flip:翻转
SortingLayer:排序层
OrderinLayer:排序值,当排序层相同时由这个值决定层级顺序
物理系统:
我们可以在Project Settings中的Physics 2D来进行相关的设置,例如Gravity可以设置重力加速度的大小和方向。
首先,我们需要在物体上挂载Rigidbody2D的组件。设置参数如下
BodyType:
Dynamic:动态,最仿真的。
Kinematic:运动,由代码控制。
Static:静态,不是为了移动设计的。
Simulated:是否模拟,不模拟没有重力碰撞等。
Mass:质量。
Linear Drag:位置移动的阻力系数。
Angular Drag:旋转移动的阻力系数
Is Kinermatic:如果只让代码控制物体而不是真实的物理模拟,勾选此项
Gravity Scale:重力系数
Collision Detection:定义如何检测2D物体之间的碰撞。
Constraints:定义对2D刚体运动的任何限制。
Material:物理材质,可以弄一个物理材质球来进行赋值,可以设置弹性和摩擦系数。
private Rigidbody2D rigidbody2D = GetComponent<Rigidbody2D>();
rigidbody2D.velocity = new Vector2(0,1); //改变速度
rigidbody2D.AddForce(Vector2.up); // 施加力
如果不仅需要重力,还需要与其他物体发生碰撞,就需要加碰撞体组件。碰撞事件至少需要有一方有刚体。
可以点击Edit Collider直接可视化编辑碰撞体尺寸。
而碰撞的检测主要靠代码完成:
// 碰撞进入
private void OnCollisionEnter2D(Collision2D col){if(col.gameObject.tag == "Bullet"){print("子弹击中");Destroy(collision.gameObject);}
}
// 碰撞中
private void OnCollisionStay2D(Collision2D col){}
// 碰撞退出
private void OnCollisionExit2D(Collision2D col){}
触发器和碰撞器同理,区别是触发器不会阻挡物体,只负责检测碰撞,只需要把碰撞器组件的is Trigger勾选上就变成触发器了,代码如下:
private void OnTriggerEnter2D(Collision2D col){if(col.gameObject.tag == "Bullet"){print("子弹击中");Destroy(collision.gameObject);}
}
// 应用这个需要把Rigidbody2D中的Sleeping Mode改为Never Sleep,否则会休眠
private void OnTriggerStay2D(Collision2D col){}
private void OnTriggerExit2D(Collision2D col){}
游戏输入介绍
主要有:键盘,鼠标,摇杆,手机触摸屏。
// 按键按下,持续按,弹起
if(Input.GetKeyDown(A)){// 按下A瞬间发生的事
}
if(Input.GetKey(A)){// 持续按A的过程中发生的事
}
if(Input.GetKeyUp(A)){// 弹起A瞬间发生的事
}if(Input.GetMouseButtonDown(0)){// 按下鼠标左键瞬间
}
if(Input.GetMouseButton(0)){// 持续按鼠标左键
}
if(Input.GetMouseButtonUp(1)){// 弹起鼠标右键瞬间
}
print(Input.mousePosition); // 输出鼠标位置,三维但第三维是0,其他两维越往左下角越小
在Edit -> ProjectSettings -> InputManager中可以设置输入按键。
用法:
// 好处是会在-1到1中平滑过度
float h = Input.GetAxis("Horizontal");
// 没有过度的用法
float c = Input.GetAxisRaw("Horizontal");
// 鼠标滚轮,向上和向下为0.1和--0.1固定值
float v = Input.GetAxis("Mouse ScrollWheel");
UI部分
Unity2D在于SpriteRenender和2D物理系统的组成,而UI在于由Canvas以及各种UI组件组成,始终附着于屏幕上,不轻易移动。
创建方法:层级面板右键菜单,里面的UI的子菜单有各种UI可以创建。
所有的UI默认都会在一个画布Canvas上创建。并且自带一个EventSystem,让我们按钮等功能可以互动。下面说一下各种组件:
Image
Image:图片组件,属性如下SourceImage:源图片,脚本中叫Sprite。注意在使用之前需要按Unity2D的方法对图片进行处理(切片等)Color:图片的叠加色RaycastTarget:是否可以作为射线目标,后续的点击拖拽需要使用。Set Native Size:恢复图片的原始尺寸。ImageType:显示模式Simple:普通模式Sliced:切片Tiled:平铺Filled:填充,血条进度条等使用。
using UnityEngine;
using UnityEngine.UI;public class Demo_Image:MonoBehaviour{private Image image;void Start(){image = GetComponent<Image>();image.color = Color.black;}
}
Text
Text:文本组件Text:文本内容Font:字体Font Style:字体样式,主要是加粗、斜体Font Size:字体大小Line Spacing:字间距RichText:富文本,有Html相关经验可以使用,否则无视Color:字体颜色Raycast Target:是否可以作为射线检测目标,可以进行点击拖动等。
Button
Button:按钮组件,由Image和Text以及Button功能组成。Image:Button物体本身的组件,使用方法同上Text:Button物体的子物体,使用方法同上Button:Button物体的组件Interactable:可交互,决定按钮是否有效。Transition:过渡方式,一般选择Color Tint改变颜色。选择Sprite Swap改变的是图片。Target Graphic:改变的Image。Normal Color:正常颜色Highlighted Color:鼠标放在上面的颜色Pressed Color:鼠标按下去的颜色Selected Color:鼠标按下去松开之后的颜色Dsabled Color:按钮不可交互的颜色Navigation:使玩家可以通过wsad和方向键来选择按钮。OnClick():按钮的交互事件,把需要执行的脚本挂载到物体上,把物体拖过来选择相应的方法即可。为了方便我们可以用代码进行操作。
Using UnityEngine;
Using UnityEngine.UI;public class Button_Click:MonoBehaviour{Button button;void Start(){button = GetComponent<Button>()button.OnClick.AddListener(ButtonClick); //代码监听事件,不用在Unity编辑器中拖拽物体了}public void ButtonClick(){Debug.Log("Button Click");}
}
InputField
InputField:输入框组件Image:InputField挂载的组件,用于显示背景图片。Placeholder:InputField的子物体,挂载text脚本,用于玩家没有输入时的文本。Text:InputField的子物体,挂载text脚本,接受玩家输入。Input Field:InputField本身的组件,部分于Button一致Text Component:接收输入的文本组件Placeholder:显示默认输入的文本组件Content Type:约束输入的内容On Value Changed:输入值改变的事件,与按钮同理On End Edit:输入结束时的事件
Using UnityEngine;
Using UnityEngine.UI;public class Button_Click:MonoBehaviour{InputField inputField;void Start(){inputField = GetComponent<InputField>()inputField.onValueChanged.AddListener(OnValueChanged); inputField.onValueChanged.AddListener(OnEndEdit); }public void OnValueChanged(string value){Debug.Log(value);}public void OnEndEdit(string value){Debug.Log(value);}
}
Toggle
Toggle:切换组件,由一个文本和一个选择框构成Background:Toggle的子物体,挂载Image组件决定选择框背景Checkmark:Background的子物体,挂载Image组件决定选中后的选择框图片(打勾)Label:Toggle的子物体,挂载Text组件显示文本Toggle:Toggle本身挂载的组件,上面的部分属性和Button相同isOn:是否被勾选上Group:重要功能,我们需要多选一时,把多个Toggle放到一个父物体下,父物体挂载ToogleGroup组件,然后拖拽父物体到这里就能实现。
Using UnityEngine;
Using UnityEngine.UI;public class Button_Click:MonoBehaviour{Toggle toggle;void Start(){toggle = GetComponent<Toggle>()toggle.onValueChanged.AddListener(OnValueChanged); }public void OnValueChanged(bool value){Debug.Log(value);}}
Slider
Slider:滑块组件Background:Slider的子物体,挂载Image组件决定了滑块的背景图片。Fill Area:Slider的子物体Fill:Fill Area的子物体,挂载Image滑块填充物的图片Handle Silde Area:Slider的子物体Handle:Handle Silde Area的子物体,挂载Image用于滑块的图片Slider:Slider本身的组件,部分参数和Button相同Direction:决定了滑块的方向Min Value:最小值Max Value:最大值Whole Numbers:数值是否为整数On Value Change:值改变时发生的事件
Using UnityEngine;
Using UnityEngine.UI;public class SliderDemo:MonoBehaviour{Slider slider;void Start(){slider = GetComponent<Slider>()slider.onValueChanged.AddListener(OnValueChanged); }public void OnValueChanged(float value){Debug.Log(value);}}
Scrollbar
Scrollbar:滚动条组件,和滑块类似,但只有背景色没有填充色,且数值范围固定为0到1Scrollbar:本身的组件,和Slider相比只有一个不同Number of Steps:滚动条有多少个可以选择的值
DropDown
DropDown:下拉菜单组件Image:挂载在DropDown本身,背景图片Dropdown:挂载在DropDown本身,部分和Button相同Caption Image:所需要改变的图片Options:选项文本和图片Value:现在的值,0为第一个,1为第二个,以此类推Alpha Fade Speed:菜单的显现速度On Value Changed:事件Label:DropDown子物体,挂载Text用于调整文本Arrow:DropDown子物体,挂载Image用于下拉箭头Template:菜单模板Viewport:遮罩Content:item:挂载toggleitem Background:挂载Image,下拉菜单背景图item Checkmark:挂载Image,下拉菜单前面的勾item Label:挂载Text,决定文本
Using UnityEngine;
Using UnityEngine.UI;public class DropDownDemo:MonoBehaviour{DropDown dropdown;void Start(){dropdown = GetComponent<DropDown>()dropdown.onValueChanged.AddListener(OnValueChanged); }public void OnValueChanged(int value){Debug.Log(value);}
}
Scroll View
遮罩组件Mask:当一个物体(例如Image)有这个组件的时候,它的子物体只有在它的范围内才可见,其他部分隐藏,相当于一个显示特定范围的窗口。
Scroll View:滚动视图Image:挂载在ScrollView本身,用于显示背景ScrollRect:本身的组件Horizontal:能否横向移动Verical:能否纵向移动Movement Type:决定如何移动Scroll Sensitivity:鼠标滚轮的灵敏度Horizontal Scrollbr:Visibility:是否隐藏Verical Scrollbr:Visibility:是否隐藏OnValueChange:事件,传过去的是Vector2的值Viewport:有个遮罩组件Content:展现内容Scrollbar Horizontal:横的滚动条Scrollbar Vertical:竖的滚动条
Using UnityEngine;
Using UnityEngine.UI;public class ScrollViewDemo:MonoBehaviour{ScrollRect scrollRect;void Start(){scrollRect = GetComponent<ScrollRect>()scrollRect.onValueChanged.AddListener(OnValueChanged); }public void OnValueChanged(Vector2 value){Debug.Log(value);}
}
Grid Layout Group
类似背包这种想要排列整齐的时候一般使用这个组件,会自动管理其下方所在其他UI元素的大小、位置等信息,层级面板不能直接创建这个组件,需要创建空物体(可以创建Image作为背景),手动添加这个组件。
Grid Layout Group:表格布局组件Image:可以在这个组件的子物体下挂载多个Image,会自动排列整齐,也可以排其他UIGrid Layout Group属性:Pedding:边距Left、Right、Top、Botton。Cell Size:格子大小Spacing:格子间距Start Corner:从哪个角开始排列
Rect Transform
一个UI元素在Canvas下时,属性不是Transform而是Rect Transform。属性如下:
- PosX,PosY,PosX:中心点的位置,z一般为0
- width,height:宽高
- Pivot:UI上中心点的位置,XY轴的范围都为0-1,旋转移动都围绕中心点进行
- anchors:左上角图标,相对于父物体的定位,可以弹性布局,重要
Canvas
场景中的画布是可以存在很多个的。有三个组件构成:
Canvas:画布Render Mode:Screen Space-Overlay表示始终位于屏幕最上层。Screen Space-Camera表示将Canvas位于相机前方,中间的2D/3D物体可以显示在UI上,可以用来展示模型。World Space表示Canvas作为一个游戏对象显示在3D场景中
Canvas Scaler:画布比例UI Scale Mode:Constant Pixel Size为固定像素,不随屏幕尺寸发生变化。Scale With Screen Size适应屏幕大小。
Graphic Raycaster:射线检测
UI事件
脚本需要继承事件接口,实现对应方法:
IpointerClickHandler:鼠标点击
IPointerDownHandler:鼠标按下
IPointerUpHandler:鼠标弹起
IPointerEnterHandler:鼠标进入
IPointerExitHandler:鼠标退出
IBeginDragHandler:开始拖拽
IDragHandler:拖拽中
IEndDragHandler:停止拖拽
using UnityEngine;
using UnigtyEngine.EventSystems;public class UIEvent:MonoBehaviour,IPointerClickHandler,IPointerDownHandler,IPointerUpHandler,IPointerEnterHandler,IPointerExitHandler
{public void OnPointerClick(PointerEventData eventData){Debug.Log("good"); }public void OnPointerDown(PointerEventData eventData){Debug.Log("good"); }public void OnPointerUp(PointerEventData eventData){Debug.Log("good"); }public void OnPointerEnter(PointerEventData eventData){Debug.Log("good"); }public void OnPointerExit(PointerEventData eventData){Debug.Log("good"); }}
Unity3D
3D和2D同理,只是多了一个z轴而已,2D中讲过的知识不再赘述。
相机调整:如果我们想将相机移动到窗口中的视角,可以选中相机后,点击GameObject->Align With View。
物理射线
用于判断是否命中,点击地面,建造物等功能。
Using UnityEngine;public class RayDemo:MonoBehaviour{void Start(){}void Update(){Ray ray = new Ray(Vector3.zero,new Vector3(0,1,0)); //起点终点定义一条射线Ray ray2 = Camera.main.ScreenPointToRay(Input.mousePotition); //鼠标点击的射线if(Physics.Raycast(ray)){Debug.Log("碰撞到物体了");}if(Physics.Raycast(ray,out RaycastHit hitinfo,1000)){ //第二个参数是碰撞信息,第三个是距离Debug.Log(string.Format("碰撞到物体{0},在{1}位置",hitinfo.collider.gameObject.name,hitinfo.point));Debug.DrawLine(ray.origin,hitinfo.point,Color.Red);//绘制射线}}}
Rigidbody
刚体移动:
Rigibody.MovePosition(Vector3 target);
target是一个具体要到达的位置
Using UnityEngine;public class RigidbodyMoveDemo:MonoBehaviour{private Rigidbody rb;void Start(){rb = GetComponent<Rigidbody>();}void FixUpdate(){Move();}void Move(){float h = Input.GetAxis("Horizontal");float v = Input.GetAxis("Verical");Vector3 offset = new Vector3(h,0,v) * 0.02f;rb.MovePosition(offset + transform.position);}
}
预制体的实例化
需求:用预制体在游戏中生成很多相同的物体,例如怪物,小兵等
using UnityEngine;
public class GenerateCube:Monobehaviour{public GameObject prefab_cube;private void Update(){Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);// 鼠标点击的地方生成物体if(Input.GetMouseButtonDown(0) && Physics.Raycast(ray,out RaycastHit hitinfo,1000)){GameObject cube = GameObject.Instantiate(prefab_cube,hitinfo.point,Quaternion.identity,transform);}}
}
Unity渲染基础
相机
Unity中的相机负责将游戏画面投放到玩家屏幕上,刚开始系统会默认存在一个Main Camera来显示画面。相机也是一个物体,它的移动导致画面的改变。
属性设置:
Clear Flags:没有物体时显示的背景,默认为Skybox(天空盒),还可以是Solid Color(纯色)。Depth Only,Don’t Clear用于多个相机同时工作。
Culling Mask:决定相机能看到哪些层
Field of View:视野大小
Clipping Planes:设置最远能看到的距离,无法观察到的贴身距离
灯光
灯光主要影响明暗程度以及阴影。Unity能模拟不同的光源如:太阳,手电筒,电灯,萤火虫等。
灯光也是一个组件,我们可以创建空物体,并添加Light来实现。也能通过右键菜单的light来实现,光源种类有:
Directional Light:平行光,一般为太阳光,全局都能照到,通过旋转能实现昼夜交替的效果。
Point Light:点光源,最常用
Spotlight:聚光灯
AreaLight:面积光,需要进行烘焙,对静态物体有用
灯光一般可以调节颜色,范围,强度,实时或者烘焙或者混合,灯光反射
光源可以分为实时的和烘焙的,实时的只对非静态的移动物体有效,烘焙的只对静态物体有效。
灯光烘焙:
Window->Rendering->Lighting Settings进入
Skybox Material:可以设置天空盒的材质
在最下方的Generate Lighting按钮可以进行烘焙
Shader
渲染管线主要分类:
- Build-in Render Pipeline(内置渲染管线):默认的渲染管线
- Universal Render Pipline(通用渲染管线):性能较好
- HD Render Pipline(高清渲染管线):以画面为主,偏向高端机器和影视的渲染管线
Shader是渲染管线的算法片段,用于告诉图形硬件如何计算和输出图像。Shader的制作基于某个渲染管线,不具备通用性,可以让模型展现出不同的效果,比如风格化等。这不是入行的必备知识,知道其作用和使用方式即可。
使用方式:将shader附加给材质球,材质球附加给网格渲染器。
粒子系统
游戏中的下雨、下雪、法球和一些技能特效都是基于粒子完成,制作由特效师完成,我们只需要使用即可。
右键菜单Effects->Particle System可以创建一个基础的粒子特效
我们只需要学习基础的Particle System的属性使用就可以了
Duration:持续事件,多少秒后不再发射粒子
Looping:是否循环播放
Start Lifetime:粒子发射出去后多少秒消失
Play On Awake:是否立刻播放粒子
Stop Action:是否在播放结束时销毁自己
动画系统
游戏动画一般指模型的动作,我们只需知道动画的运行原理,不是动画设计师的我们不会过于深入动作本身的设计。我们的学习重点是给角色配置动作、切换动作、代码控制动作等。
想要让一个角色拥有动画,需要几个步骤:
- 挂载Animator组件
- 给Animator组件配置Controller,我们需要右键菜单创建一个,赋值给它
- 双击Controller可以打开Animator窗口,我们需要在这里配置动画
- 我们可以把动画的片段拖动进来,通过配置各种状态转换的关系达到目的,右键菜单创建的Animation可以创建动画片段(一般由美术提供)
简要动画制作:
- 双击动画片段可以打开Animation窗口,可以在这里编辑具体的动画
- Preview可以查看Animator拥有的动画片段
- 点击红色圈可以开始录制动画,我们可以随意拖动物体到我们想要的姿势,再次点击红圈结束录制,点击播放按钮后动画会以平滑的方式完成转变。
Animator Controller
配置动画片段:单击Animation片段,可以看到有几个属性可以设置,Loop Time代表动画是否循环播放,Loop Pose让收尾连接更平滑。
- 首先Animator默认有三个状态,Entry是起始点,Any State是指任何状态,方便我们进行一些转换操作,Exit指退出,不再执行动画。
- 对着拖进来的动画片段点击右键,Make Transition可以设置连接关系,Set as Layer Default State可以设置默认状态。
- 点击连接Animation的箭头,一般我们用代码控制特定变量的改变,然后就能在Conditions里设置转换条件,我们可以在Animator窗口的Parameters中设置特定变量
- Has Exit Time代表是否播放完动画再转换状态
- Settings中的Fixed Duration代表是否有动画过渡,并可以设定过渡时间
- 单击动画片段块,我们可以设置属性,Speed代表动画播放速度。下面的Transitions可以设置转换的哪个状态单独有效(solo),或者哪个无效(Mute)
代码控制:
using UnityEngine;public class AnimatorDemo:MonoBehaviour{
private Animator animator;void Start(){animator = GetComponent<Animator>();}void Update(){if(Input.GetKeyDown(KeyCode.Space)){animator.SetTrigger("跳一跳"); //改变Int,float,bool值同理}}
}
注意:需要在Parameters中设置以“跳一跳”为名的Trigger变量,然后在转换箭头中设置好transition。
人性角色的骨骼结构是一致的,我们需要有Avatar映射文件,可以让动作复用。
动画事件
在Animation窗口中,我们选中一个动画,选中一帧,然后点击Add event(一个白色柱状下方一个小尖的标志),这样就可以在这一帧添加一个事件,我们可以在这里执行想要的方法,可以从该物体挂载的脚本下选择。
注意:如果是导入的模型,可能无法在animation界面添加事件,我们需要找到对应的动画模型,点击Inspector中的Animation,下方有一个Event的属性,可以进行设置。但不支持两个及以上的事件。
角色控制器组件
首先,我们给需要控制的物体挂载Character Controller组件。设置参数:
- Slope Limit:最大爬坡的角度,45指最大能爬45度的坡
- Step Offset:最高能无视多少高度的阶梯
- skin Width:皮肤厚度,相当于一个隔空的碰撞器
- Min Move Distance:最小的移动距离,小于该值不会移动
- Center:碰撞器的中心
- Radius:碰撞器半径
- Heiget:碰撞器高度
注意:角色控制器所在的游戏物体不需要碰撞体和刚体
using UnityEngine;public class CCDemo:Monobehaviour{private CharacterController characterController;void Start(){characterController = GetComponent<CharacterController>();}void Update(){Debug.Log(characterController.isGrounded);float h = Input.GetAxis("Horizontal");float v = Input.GetAxis("Verical");//Vector3 dir = new Vector3(h,-9.8f,v); //-9.8模拟重力//characterController.Move(dir * Time.DeltaTime * 10);characterController.SimpleMove(dir * 10);//传入速度,并且不会被帧率影响,并且包含重力}}
导航系统
功能需求:我们点击地图上得某个位置,角色需要自动跑到这个位置,并且还具有规避障碍物的功能。
以上的功能叫导航,也叫寻路,用到的组件是NavMeshAgent。
在导航之前,我们需要确定哪些地方是能去的,哪些是不能去的:
- 我们把所有不能动的物体全部勾上static
- Window->AI->Navigation->Bake->Bake
- 烘焙之后场景中蓝色的部分就是角色可以去的地方
然后我们就可以在角色上挂载并设置NavMeshAgent组件了:
Base Offset:导航组件碰撞体的高度
Speed:导航速度
Angular:导航旋转速度
Acceleration:导航加速度
Stopping Distance:判定到达终点的停止距离
Auto Braking:到达终点自动停止
Radius:导航碰撞体半径
Height:导航碰撞体高度
Quality:质量越高越智能
使用方法:
using UnityEngine.AI;
using UntiyEngine;public class NavDemo:MonoBehaviour{public NavMeshAgent agent;public Transform target;void Start(){agent = GetComponent<NavMeshAgent>();}void Update(){agent.SetDestination(target.position);if(Input.GetKeyDown(KeyCode.Space){agent.isStopped = !agent.isStopped;})}}
Navigation面板
Window->AI->Navigation进入面板,上面使用的是烘焙(bake)功能。
Agents面板不常用,不作讲解,在多个导航网格对应不同的agent类型使用,有需要可以查阅官方资料。
Areas面板用来区分区域,不同的区域行走代价不同,陆地比沼泽走得更快,导航会选择行走代价低的地方进行。但是,这并不会影响到实际的行走速度,行走速度由代码控制,这里只是另外设定的一个代价值而已。
Object面板,点击一个静态物体后,上面有一个Navigation Area的选项,可以选择Areas面板的设定值,决定在上面行走的行走代价。
NavMeshObstacle
有的时候,我们需要动态生产障碍物(例如释放阻拦型技能),我们也需要把它放进导航的考量范围内。我们只需要给生成的障碍物添加NavMeshObstacle组件即可。正常设置障碍物的导航碰撞体形状即可,勾上属性Carve后即可把障碍物考虑在内。
资源管理
资源导出
当我们想把某些游戏资源打包发给别人的时候,我们选中资源->右键菜单->Export Package
注意:资源上的材质球等信息如果不和预制体一起导出,会导致预制体材质球丢失,其他同理。导入时直接拖拽即可
Resource资源加载
当我们需要把资源动态地加载近游戏中,我们需要创建一个Resources文件夹,在什么地方都可以,多个Resources文件夹路径会合并。
代码加载:
private GameObject prefab_cube;
prefab_cube = Resources.Load<GameObject>("Prefabs/Cube");//参数传入Resources文件夹下的路径
数据存档
单机游戏的数据存放在本地,网络游戏重要数据存放在服务端的数据库,不关键的数据存放在本地。PlayerPrefs是Unity为我们提供的方式。
数据储存在注册表HKEY_CURRENT_USER/Software[company name][product name]下
打开方式cmd中regedit.exe
// 储存数据
PlayerPrefs.SetString("PlayerName","Xiaoxing");
PlayerPrefs.SetFloat("Distance",2.2f);
PlayerPrefs.SetInt("Age",24);// 获取数据
if(PlayerPrefs.HasKey("Age")){int Age = PlayerPrefs.GetInt("Age");
}
if(PlayerPrefs.HasKey("PlayerName")){string playerName = PlayerPrefs.GetString("PlayerName");
}// 删除数据
PlayerPrefs.DeleteAll(); //全部数据
PlayerPrefs.DeleteKey("Name"); //指定数据
游戏场景加载
很多时候,我们不能在一个场景中完成所有的事情,需要根据功能划分场景,例如:登录场景,游戏大厅,战斗场景等
场景切换
前提:场景必须被打包,在File->Build Setting中把场景拖拽金Scenes In Build,排序第一的作为开场场景。
using UnityEngine;
using UnityEngine.SceneManagement;public class SceneDemo:MonoBehaviour{void Update(){if(Input.GetKeyDown(KeyCode.A)){SceneManager.LoadScene(1); //加载第二个场景SceneManager.LoadScene("Scene"); //加载对应名称的场景}}
}
数据保留
加载场景默认销毁上一个场景所有物体,如果想保留部分物体:
GameObject.DontDestroyOnLoad(gameObject); // 保留自身
声音系统
在相机上有一个AudioListener组件,没有它玩家听不到声音。这个东西相当于声音接收器,声源近则声音大,并且有左右声道。
相对地,发出声音的物体身上挂载的是AudioSource组件。
AudioClip:声音片段
Mute:是否静音
Play On Awake:生成游戏物体时立刻播放音频
Loop:循环播放
Volumn:音量
Pitch:音调,默认为1,值越大,速度越快,音调越高
Stereo Pan:声道占比
AudioSource audiosoruce;
public AudioClip clip;
audioSource.clip = clip;
audioSource.Play();
audioSource.Stop();
if(audioSource.isPlaying)audioSource.Pause();
audioSource.UnPause();audioSource.PlayOneShot(clip); //播放一次,可以叠加
Windows打包发布
把Unity的工程项目变成玩家可以打开的exe文件
File->Build Setting->Player Setting
这里可以设置公司名称,产品名称版本等信息
Default Cursor:有两张图片,第一张设定游戏图标,第二张设置鼠标指针图标
Resolution and Presentation:
Fullscreen:窗口还是全屏运行
Default is Native Resolution:打勾代表自动设置分辨率,否则要手动设置
一切设定玩了后可以点击Build,选择路径,游戏就能顺利导出到对应路径啦!