Unity以及游戏源码
基本认识
-
FixedUpdate:每秒50次刷新:50帧,注意条件变量的控制(二段跳)
-
单词
-
gravity:重力
-
Rigdbody:刚体
-
-
Unity
-
组件名在vs中不能更改,且vs要求组件名必须首字母大写;
-
视角跟随:在unity中选中GameObject为Sphere
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraControler : MonoBehaviour
{
public GameObject Sphere;//在unity中选中GameObject为Sphere
private Vector3 offset;
// Start is called before the first frame update
void Start()
{
offset = transform.position - Sphere.transform.position;
}
// Update is called once per frame
void LateUpdate()
{
transform.position = Sphere.transform.position + offset;
}
}分辨率:一个格子100dp=10*10;
物体碰撞(2d):
-
物体设置为Rigidbody、Boxcollider,地面设置为Rigidbody并将bodytype修改为Kinematic、Boxcollider
-
碰撞会产生微小形变,可能会穿模,将主角的Rigidbody中的Interpolate改为Interpolate去除碰撞形变
-
物体运动
https://www.bilibili.com/video/BV14V411r7Tr?p=2视频教学
Kinematic:开启运动学,开启后不再受力的影响,只能通过Transform属性来操作。
-
初级运动
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Character : MonoBehaviour
{
public float speed = 3f;
public Rigidbody2D rig;
public float jumpForce;
// Start is called before the first frame update
void Start()
{
rig = GetComponent<Rigidbody2D>();
jumpForce = 300f;
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.K))
{ //如果按下空格
rig.AddForce(new Vector2(0, jumpForce)); //给刚体一个向上的力
}
float moveX = Input.GetAxisRaw("Horizontal");//控制水平方向A:-1 D:1 0
//float moveY = Input.GetAxisRaw("Vertical");//控制数值方向S:-1 W:1 0
Vector2 position = transform.position;
position.x += moveX * speed * Time.deltaTime;
transform.position = position;
}
} -
高级
-
改为没有平滑过渡Editor--Project setting--Input--Gravity、Sensetivity修改为1000,与fire1相同
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Character : MonoBehaviour
{
public float WalkSpeed;
public float AccelerrateTime;
public float DecelerateTime;
Rigidbody2D Rig;
float velocityX;
private void Awake()
{
Rig = GetComponent<Rigidbody2D>();
}
private void FixedUpdate()
{
if (Input.GetAxisRaw("Horizontal") < 0)
{
Rig.velocity = new Vector2(Mathf.SmoothDamp(Rig.velocity.x, WalkSpeed * Time.deltaTime * 60, ref velocityX, AccelerrateTime), Rig.velocity.y);
}
else if (Input.GetAxisRaw("Horizontal") > 0)
{
Rig.velocity = new Vector2(Mathf.SmoothDamp(Rig.velocity.x, WalkSpeed * Time.deltaTime * 60*(-1), ref velocityX, AccelerrateTime), Rig.velocity.y);
//使用加速时间控制启动、停止快慢
}
else if (Input.GetAxisRaw("Horizontal") == 0)
{
Rig.velocity = new Vector2(Mathf.SmoothDamp(Rig.velocity.x, 0, ref velocityX, AccelerrateTime), Rig.velocity.y);
}
}
}
-
使用
在Edit->project setting -> input 处可以对按键细节进行设置: 扩展size ,即可添加按键配置。 Name:名称,调用或在外部设置的时候需要使用该名 Negative Button :缺省值为-1的按键 Positive Button :缺省值为1的按键 Alt Negative Button :备用的缺省值为-1的按键 Alt Positive Button :备用的缺省值为1的按键 Dead: 输入阈值, 触摸或者摇杆大于这个值才会触发输入 Gravity:表示松开按键时,从端点1或-1返回缺省值0时的速度 Sensitivity:按下按键时,从缺省值0到1或-1时的速度 Snap: 当触发反向操作时,当前值是否立即归零 Invet:是否取反值 Type:预设输入设备类型,可选键盘与鼠标按键、手柄、鼠标移动 Axis:装置选择,例如一个手柄有两个十字键两个摇杆,那么可以在这里设置当前设定作用于哪个装置 Joy Num: 手柄编号。指定连接的哪个设备 需要说明的是,在输入管理器中设置的输入基本上都是返回-1 - 1 区间的值。这比返回true false要好很多,因为优化输入体验的时候,比如我们希望根据按压力度来调整跳跃距离,又或者我们希望根据摇杆的摇摆程度来控制车辆的方向盘,都比较合适
函数说明
Rig.velocity:刚体的速度:矢量,
参数说明
Parameters,它就是使用Animator来切换动作的灵魂。可以把它理解为实现动作的条件,通过改变它来判断满足什么条件执行什么动作。点击右边的+号,可以看到有4个类型:Float,Int,Bool,Trigger。
绘制背景
-
创建tilemap
-
设置sortinglayer:通过Edit/Project Settings/Tags & Layers打开Sorting Layers创建*排列层*并调整它们的位置
-
放入背景,设置每个tilemap单元格的像素(设置tilemap的scale大小,自己调试)
第一次人物做的太小,导致画地图时地图方块无法占满单个格子
-
调试物块大小:将物块放入tilepalete,在inspector界面中调整图片像素
设置地图
-
在对应的tilemap里边添加碰撞器,刚体
-
单独的每一块碰撞器,发现角色卡在某个位置不能移动,解决方法:将每个碰撞器合并成整体的复合碰撞器
-
Tilemap Collidor 2d中选择used by Composite
-
添加Composite Collidor 2d
-
-
调整TileMap碰撞点
在进行爬坡测试的时候,出现了一个问题就是斜坡的瓦片碰撞点不能和瓦片重合,且凹凸不平,运行体验不佳。
不是正方形的瓦片的话,TileMap的碰撞点自动设置可能很奇怪,直接TileMap设置碰撞器的话,可能会有凹凸不平的情况,且凹凸不平的形状不能和瓦片完全重合。
出现这个问题可能需要回到一开始编辑图片,在Sprite Editor里面,左边的红框选择第三个Custom Physics Shape,然后点击需要修改碰撞点的方形块,然后点击Generate就可以修改碰撞点。
-
物体勾选IsTriger:物体可以被穿过但仍视为有效碰撞,用于制作陷阱或者拾取道具
动画制作
-
创建空动画
-
将动画拉入主角,自动生成动画控制器
-
点击Animator,右键创建blendtree
-
点击blendtree,再双击,添加之前创建的空动画
-
选择主角,在animation处添加图片,生成动画
动画重写
-
已有Enermy1动画效果,在AnimationControllers文件夹内空白处右键,依次选择Create->Animator Override Controller,创建了一个动画重写控制器,我们命名为Enemy2。
-
可以看到这个重写控制器右侧Inspector窗口内有个Controller选项,可以选择继承哪个动画控制器。在这里,我们可以把Enemy1直接拖入到输入框,或者点击输入框右侧的小圆圈选择Enemy1。
-
继承Enemy1的动画控制器后,还需要把美术资源也替换掉。Enemy1Attack改写成Enemy2Attack,Enemy1Idle改写成Enemy2Idle,这样重写控制器就配置好了。
-
这时候,怪物2的Animator组件使用的控制器还是Enemy1。选择Enemy2游戏对象,在Animator组件的Controller选项点击右侧小圆圈,在弹出的窗口中选择Enemy2即可。
-
这时候运行游戏,可以看到怪物2的动画正常。
-
通过这样重写控制器,以后在怪物1的动画控制器添加逻辑的时候,怪物2自动继承,不需要再额外给怪物2添加一样的逻辑。我们这个项目才2个小怪,如果怪物类型或者动画类型再多一点,重写控制器就非常有必要。而且修改起来也只需要改一个地方即可,非常方便。其实个人觉得和Prefab预制件有点相似。
链接:https://www.jianshu.com/p/5622f6db56b7
game
实现高度手感跳跃
public float LowJumpMultiplier;
bool IsJumping;
//触地判定
public Vector2 PointOffset;
public Vector2 Size;
public LayerMask GroundLayerMask;
Rigidbody2D Rig;
float velocityX;
bool GravatySwitch = true;
bool IsOnGround;//判定是否在地面
private void Awake()
{
Rig = GetComponent<Rigidbody2D>();
}
private void FixedUpdate()
{
IsOnGround = OnGround();
//左右移动
if (Input.GetAxisRaw("Horizontal") < 0)
{
Rig.velocity = new Vector2(Mathf.SmoothDamp(Rig.velocity.x, WalkSpeed * Time.deltaTime * 60*(-1), ref velocityX, AccelerrateTime), Rig.velocity.y);
}
else if (Input.GetAxisRaw("Horizontal") > 0)
{
Rig.velocity = new Vector2(Mathf.SmoothDamp(Rig.velocity.x, WalkSpeed * Time.deltaTime * 60, ref velocityX, AccelerrateTime), Rig.velocity.y);
}
else if (Input.GetAxisRaw("Horizontal") == 0)
{
Rig.velocity = new Vector2(Mathf.SmoothDamp(Rig.velocity.x, 0, ref velocityX, AccelerrateTime), Rig.velocity.y);
}
if (Input.GetAxisRaw("Jump") == 1&&!IsJumping)
{
Rig.velocity = new Vector2(Rig.velocity.x, JumpingSpeed);//x轴不变,y轴给个初速度
IsJumping = true;//正在空中
}
if (IsOnGround && Input.GetAxisRaw("Jump") == 0)//在地面并且松开跳跃键
{
IsJumping = false;
}
//Physics2D.gravity.y是一个负值
if (Rig.velocity.y < 0)//下坠时
{
//下落的更快
Rig.velocity += Vector2.up * Physics2D.gravity.y * (FallMultiplier - 1) * Time.fixedDeltaTime;
}
else if(Rig.velocity.y>0&&Input.GetAxisRaw(