print()
print()
其实 GetKeyDown 比 GetKey 更符合逻辑,因为转向是一次性的,玩家不可能通过持续按一个键来完成连续转向。
public int xlimit= 21;
public int ylimit= 11;
public int xoffset= 7;
public GameObject foodprefab:
public Sprite[] foodsprites;
private Transform foodHolder;
void Start()
foodHolder=GameObject.Find("FoodHolder").transform; MakeFood();
void MakeFood(){
int index = Random.Range(0,foodsprites.Length);
GameObject food = Instantiate(foodPrefab);
food.GetComponent<Image>().sprite=foodsprites[index];
food.transform.SetParent(foodHolder,false);
int x= Random.Range(-xlimit +xoffset,xlimit);
int y = Random.Range(-ylimit,ylimit);
food.transform.localPosition = new Vector3(x* 30,y* 30,0);
}
gameObject.transform.localRotation= Quaternion.Euler(0,0,0);
gameObject.transform.localRotation= Quaternion.Euler(0,0,180);
gameObject.transform.localRotation= Quaternion.Euler(0,0,90);
gameObject.transform.localRotation= Quaternion.Euler(0,0,-90);
if(Input.GetKeyDown(KeyCode.Space))
{
CancelInvoke();//取消invoke(调用),先停住,在改数值
InvokeRepeating("Move",0,velocity -0.2f);
}
分析:
蛇每次走多少,用一个 step值
定义两个私有变量 下 x y,就是蛇下一步走多少的增量
public float velocity = 0.36f
public int step;
private int x;
private int y;
private Vector3 headPos;
要调用move
InvokeRepeating("Move",0,velocity);//重复调用
x=step; y=0;//一开始就向右走
移动按键
void update{
if(Input.GetKey(KeyCode.W))
{
x=0; y=step;
}
if(Input.GetKey(KeyCode.S)){
x=0; y=-step;
}
if(Input.GetKey(KeyCode.A))
x=-step; y= 0;}
if(Input.GetKey(KeyCode.D)){
x= step; y =0 ;}
}
void Move(){
headpos =gameObject.transform.localPosition;
gameObject.transform.localPosition=new Vector3(headPos.x+x,headPos.y+y,headPos.z);
}
发布游戏 file buildsetting 看下playersettings
build 保存
bug 如果之前运行过unity 分辨力格式会变 win+r 输入 regedit 打开注册表管理器
把unity editor 里的东西删掉
对用户设置的储存
给start脚本写一个脚本UI
变量 两个文本组件持有
方法
Awake 里拿一下得分PlayerPrefs
回到开始场景回到游戏里用空物体先reset一下tranform挂上脚本 然后托好物体
再做一下start(GO)的按钮
方法用public 在帮一下监听事件 两个按钮的
这里一个ScriptHolder 控制两个场景 确实妙
才发现之前换行符写成除号了
皮肤与模式的设置(toggle)
方法 四个方法 注意特殊的bool isOn 动态bool(只有false转到true才会调用)
拖好方法
先把皮肤蛇头蛇身文件名储存下来PlayerPrefs(后面的是文件名)
border 用SetInt 没有setBool这个选项
上次设置的读取
start方法里一开始是蓝色的蛇 读取sh 默认sh01判断是否是蓝蛇
打勾 blue.isOn = true
其他一样的思路
变量还要把4个toggle 拿进来
死亡方法与特效
放在蛇头里
方法Die CancelInvoke
变量 状态 bool 拿爆炸特效GameObject 拖一下特效
特效播放就是实例化
协程(也叫接口?)来控制等一会重载场景(控制特效)
命名空间
IEnumerator(这是返回值) GameOver(float t)
yield return new WaitForSeconds(t);(看到这句话就会等待一下再执行下面的代码 括号内得是参数
死亡后记录得分
unity自带类
PalyerPrefs.SetInt("last1", MainUIController.Instance.length) ; 要记录的都是整数(名字加东西)
最佳的分判断 结构与上面记录一样 以0开始 判断后记录 记录后下次直接返回的就是这个值
这里就更加体现在记录数据系统中单例的重要性
暂停游戏与返回菜单的开发
变量 bool记录状态 持有暂停按钮 暂停图片组图片组
public Button pauseButton;
public Sprite[] pauseSprites;
private bool isPause = false;
方法 暂停的方法 自己的UI Button被按下
先取反 !
换里面的Image图片 上面错了 改成Image类型
给暂停按钮绑定监听事件 再在原脚本里拖赋值
控制冲突 Input
修改移动方法的bug
主页按钮的返回功能
分数与长度的记录 nameSpace 空间
变量 分数/长度 两个公共text 注意Text 类型要大写 拖 拿到背景
方法一 做一个改UI的方法
单例 要加一个单例因为要在外面访问 直接把那个复制过来 我觉得可以建一个模板库
awake里 给单例赋值
再在sh脚本里吃掉方法里调用更新UI方法
方法2 等级成长 score/100 switch 换背景
改颜色 bgImage.color=new Color();
color tool用#号: ColorUtility.TryParseHtmlString((#。。。,out 输出的参数) 要一个东西存一下private Color tempColor;
颜色编号顺序 蓝绿黄橙红
奖励生成
reward prefab
额外生成
给makefood 加一个形参 bool isReward
start里将其设为flase
在sh里的调用 做一个判断 用随机数1~100来做一个概率器
true的时候额外生成
奖励目标生成把食物的语法复制一下 把int删掉就不用改名了 把名字改全
再在碰撞器里加一下判断
边界传送
加body的tag
再碰撞方法里加入该标签的判断 (这都是模板了)方法留空Debug.Log 多边界用switch
直接把蛇头坐标移到对面 弹下去还要走一步以避免碰撞
按30一格就是好算
注意case是冒号
for 循环循环移动 从后往前 利用上一个的位置
在sh里找到canvas 的transform(定义的canvas类型是transform)
不好的方法 最后一个依次移到第一个 last方法要引入linking namespace
-1 是最后一个
蛇身的生成
跟蛇头一样做预制体
上面要引入UI
用List来存蛇身
变量 拿预制体
还有一个图片数组 两段不同颜色
生成方法 实例化预制体 位置先不管
数组奇数偶数图片不一样 来一个判断index
?就是等于0 : 否则等于1
相同操作 找渲染器/ setParent 拿canvas
再把多的身子(transform)加入List
再在Move后调用
碰撞销毁再生成
给蛇头填collider 再填size 精准碰撞 小于30 trigger(不会和别人发生碰撞 但会检测谁撞到了我)(两边只能钩一个)
刚体 给食物+Tag
On。。。方法 括号中间无逗号!!! 两种识别标签的方法只记一种
怎么通知Maker呢
在Maker中创建一个静态的单例模式 可以直接从类名来访问它
再用一个变量 访问get 直接 return _instance给他!把它转变为私有
再在sh下加入访问Instance 记得把Makefood 改成public
再在Awake()里给他_instance里赋值this(必须赋值)
食物随机生成 step的整数倍 从000到上端 11步
-11~11(*30) 21步右 左13
变量 上下左右限制 预制体公共 foodHolder transform
只需一个预制体 到时候直接填图片即可 (同质)
图片数组
方法
1start里找到 foodHolder.transform
2存下索引 随机遍历 实例化 坐标随机 再赋给food vector3坐标 这样的话就不用在Instantiate里写坐标了
3再拿到food身上的image组件。sprite=数组 索引
4加上unityUI的namespace
最后在start里调用makefood 还要专门找一个物体来放这个脚本
而之前是用数组 再随机?
吃掉再生成
再创建一个空物体?锚点 四周定位 把创建出来的食物放在他的子物体 SetParent(这个可以说是很常见了 flase 不然会自动缩放
UGUI 直接.transform 不需要GetCom。。。
旋转 位置等于四元数 加在转向里(x,y,z,)这里只用控制z轴 注意此时是LocalRotaion
一开始的初始方向要与旋转角度一致
Bug 不能直接180度转 会撞身子
按下加速 抬起恢复
这时的速度是Invoke的间隔参数
我们先用CancelInvoke()取消Invoke
再重写改速度。
蛇头及其移动
UGUI image 45,45 做成预制体
蛇头脚本
变量: 每格走的距离1 增量值 头坐标 间隔速度
move的方法. transform.localPosition(UGUI专用)直接赋值坐标
注意Vector3大写
监听 写在Update里!
if(不用getkeydown因为可以一直摁着
反复调用Move 再放进Start方法里!InvokeRepeating 只要传字符串即可 (方法,延时,间隔)间隔直接视作速度
Ad: 一上来就会动 设置xy初始值 start里
说明这里的update只管转向 我们在start里不断重复作step运动