学习
资料
https://developers.weixin.qq.com/miniprogram/dev/framework/ 官方资料
https://developers.weixin.qq.com/minigame/dev/guide/ 小游戏v
https://mp.weixin.qq.com/ 注册页面
https://unity.cn/tuanjie/releases?signup=true#undefined 小游戏页面
unity 项目代码
https://github.com/HerrQQ/gameLearning
unity 基础学习
体会
- 整体感觉和matlab类似 是代码可视化的编辑器:类和方法可视化gui修改, 工具库调试运行直接看结果,还有算法库的集成,直接使用接口。
- 一定修改编辑器运行时颜色 具体见学习笔记
- 善用Tag
学习笔记
教程地址:
https://learn.u3d.cn/tutorial/indie-game-project?chapterId=63562b26edca72001f21d055#628a743237e2ac001fd3b40d
一定要设置 playmode的提示 否则修改白改 推荐用颜色提醒
不需要自己安装scripts 运行c#
Unity 的脚本设计高度依赖其引擎架构和编辑器工具链,scriptcs 作为通用 C# 脚本工具,无法替代 Unity 的原生执行流程。开发者应通过 Unity 编辑器直接编写、挂载和运行脚本,以确保功能完整性和性能优化自动安装失败的话 需要自己安装一下 visual studio 并在设置中关联一下
教程中的我们可以用gitbug git vscode都可以没有必要硬搬
暂时成果 1
创建Resource文件夹 用来保存一些使用的资源
管理了不同场景有什么
- 可以不加刚体?
- 文件夹功能
常见的回调函数总结
在Unity中,回调函数是由引擎自动触发的特定方法,用于在游戏对象生命周期的不同阶段执行逻辑。以下是常见的回调函数分类及作用,结合Unity的官方文档和开发者实践总结:
1. 初始化阶段
• Awake()
• 调用时机:脚本实例加载时(无论脚本是否启用)。
• 用途:初始化变量或组件引用(如GetComponent),但不保证其他对象的Awake已执行。
• 执行次数:仅一次。
• OnEnable()
• 调用时机:脚本或游戏对象被激活时(如SetActive(true))。
• 用途:注册事件监听、启用组件。
• 执行次数:每次激活时调用。
• Start()
• 调用时机:在Awake之后、第一帧Update之前,仅当脚本启用时调用。
• 用途:依赖其他对象的初始化(如查找场景中的玩家)。
2. 物理与碰撞阶段
• FixedUpdate()
• 调用时机:固定时间间隔(默认0.02秒),与帧率无关。
• 用途:处理物理计算(如刚体移动、力施加)。
• OnTriggerEnter/Exit/Stay()
• 触发条件:碰撞体勾选Is Trigger且双方有刚体或碰撞体。
• 用途:检测触发器事件(如拾取奖励、进入区域)。
• OnCollisionEnter/Exit/Stay()
• 触发条件:非触发器的物理碰撞。
• 用途:处理物体反弹、伤害计算等。
3. 游戏逻辑更新阶段
• Update()
• 调用时机:每帧调用一次,频率与设备性能相关。
• 用途:处理输入、动画、非物理逻辑(如角色移动)。
• LateUpdate()
• 调用时机:所有Update执行完毕后。
• 用途:摄像机跟随、依赖其他对象位置的逻辑。
4. 渲染与GUI阶段
• OnGUI()
• 调用时机:每帧调用多次(用于渲染IMGUI元素)。
• 用途:绘制调试界面或简单UI(现代UI推荐使用UGUI)。
• OnPreRender() / OnPostRender()
• 调用时机:摄像机渲染前后(仅挂载到摄像机的脚本)。
• 用途:自定义后期处理或渲染效果。
5. 销毁与清理阶段
• OnDisable()
• 调用时机:脚本或对象被禁用时。
• 用途:取消事件订阅、释放临时资源。
• OnDestroy()
• 调用时机:对象被销毁时(如Destroy(gameObject))。
• 用途:清理持久化数据或网络连接。
6. 其他重要回调
• OnApplicationPause()
• 触发条件:应用暂停(如切到后台)。
• 用途:保存游戏状态或暂停音效。
• OnMouseDown() / OnMouseOver()
• 触发条件:鼠标与带碰撞体的对象交互。
• 用途:实现点击或悬停反馈。
回调函数执行顺序示例
1. Awake → OnEnable → Start(初始化)
2. FixedUpdate → OnTriggerXXX → Update → LateUpdate(每帧循环)
3. OnDisable → OnDestroy(销毁)。
注意事项
• 脚本需继承MonoBehaviour:否则回调无效。
• 避免耗时操作:如Update中频繁实例化对象,可能引发性能问题。
• 多脚本执行顺序:通过Script Execution Order调整优先级。
如需更详细的调用顺序图,可参考Unity官方文档中的生命周期图示。
常见查询函数
在Unity开发中,类似transform.Find("ScoreTex").GetComponent<Text>()这样通过层级查找和组件获取的接口或方法非常常见,以下是综合多个搜索结果整理的高频使用场景及对应方法:
1. 组件查找与获取
• GetComponent<T>()
获取当前对象上的指定类型组件(如Text、Rigidbody),若不存在返回null。
var text = GetComponent<Text>(); // 获取当前对象的Text组件
• GetComponentInChildren<T>()
递归查找子对象中的组件(包括自身),适用于嵌套结构的UI或复杂对象。
var collider = GetComponentInChildren<Collider2D>(); // 查找子物体中的碰撞体
• GetComponentsInParent<T>()
查找父对象链中的所有匹配组件,常用于共享逻辑(如父级控制器)。
var renderers = GetComponentsInParent<MeshRenderer>(); // 获取所有父级渲染器
2. 层级与场景对象查找
• transform.Find("路径")
通过路径名查找子对象(需完整路径,支持斜杠分隔)。
var child = transform.Find("Canvas/ScoreTex"); // 查找嵌套子对象
• GameObject.Find("对象名")
全局查找场景中激活的对象(性能开销大,慎用)。
var player = GameObject.Find("Player"); // 查找场景中的玩家对象
• FindGameObjectWithTag("标签")
通过标签快速查找对象(如"Player"、"Enemy")。
var enemy = GameObject.FindGameObjectWithTag("Enemy"); // 查找带标签的敌人
3. 动态创建与销毁
• Instantiate(prefab)
实例化预制体或对象,常用于生成子弹、敌人等。
var bullet = Instantiate(bulletPrefab, spawnPoint.position, Quaternion.identity);
• Destroy(gameObject)
销毁对象或组件(如拾取后移除奖励物品)。
Destroy(collision.gameObject); // 销毁触发碰撞的对象
4. 输入与事件处理
• Input.GetAxis("Horizontal")
获取平滑输入轴(如-1到1的键盘/手柄输入)。
float moveX = Input.GetAxis("Horizontal"); // 角色水平移动
• EventSystem.current.RaycastAll()
UI射线检测,用于判断点击是否落在UI元素上。
var results = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventData, results); // 检测UI点击
5. 协程与异步控制
• StartCoroutine(IEnumerator)
启动协程,实现延迟或分帧逻辑(如技能冷却)。
StartCoroutine(RespawnAfterDelay(3f)); // 3秒后重生
• yield return new WaitForSeconds(time)
协程中等待指定时间,不阻塞主线程。
yield return new WaitForSeconds(1f); // 等待1秒
6. 物理与碰撞检测
• Physics2D.Raycast(origin, direction)
2D射线检测,用于判断前方是否有障碍物。
RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.right, 1f);
• OnCollisionEnter2D(Collision2D)
物理碰撞回调,处理非触发器碰撞逻辑。
void OnCollisionEnter2D(Collision2D collision) {
if (collision.gameObject.CompareTag("Wall")) { /*...*/ }
}
7. UI控制
• CanvasGroup.alpha
控制UI组的透明度(如淡入淡出效果)。
GetComponent<CanvasGroup>().alpha = 0.5f; // 半透明效果
• Button.onClick.AddListener()
动态绑定按钮点击事件。
button.onClick.AddListener(() => Debug.Log("Clicked!"));
8. 时间与数学工具
• Time.deltaTime
帧间隔时间,用于平滑运动(避免帧率影响速度)。
transform.Translate(Vector3.forward * speed * Time.deltaTime);
• Mathf.Clamp(value, min, max)
限制数值范围(如血量不低于0)。
health = Mathf.Clamp(health, 0, 100);
总结
以上方法覆盖了Unity开发中的对象查找、组件操作、物理交互、UI控制等核心场景。实际开发中需注意:
1. 性能优化:避免在Update中频繁使用Find或GetComponent,建议在Start或Awake中缓存引用。
2. 上下文适配:如2D游戏优先使用Physics2D系列方法,3D游戏使用Physics。
3. 事件驱动:多用回调(如OnTriggerEnter)而非轮询检测。
关于 C sharp的一些疑问和记录
在Visual Studio(VS)中,Unity的C#工程中一个文件可以直接使用另一个文件中定义的类而不需要类似C++的显式头文件导入,主要原因在于C#和Unity项目的编译机制、命名空间管理以及IDE的自动化处理方式与C++有本质差异。以下是具体分析:
1. C#的命名空间与程序集机制
• 命名空间(Namespace)自动可见性
C#中同一项目内的所有文件默认属于同一程序集(Assembly),只要类定义在相同或已引用的命名空间中,其他文件可直接访问,无需手动“导入”。例如:
// FileA.cs
namespace GameLogic {
public class Player { /*...*/ }
}
// FileB.cs
using GameLogic; // 可省略(若在同一命名空间)
public class GameManager {
private Player player; // 直接使用Player类
}
若类位于不同命名空间,仅需在文件顶部添加using语句(非头文件,仅声明命名空间)。
• 程序集引用替代头文件
C#通过项目引用(如.csproj文件中的<ProjectReference>)或DLL引用隐式关联依赖,编译器会自动解析所有关联文件,无需像C++那样通过头文件声明接口。
2. Unity项目的特殊编译流程
• 动态生成解决方案文件
Unity在点击“Open C# Project”时会动态生成.sln和.csproj文件,自动包含项目中所有C#脚本的依赖关系。因此,即使未手动配置,VS也能识别跨文件的类引用。
• 全局脚本编译
Unity将所有脚本视为同一编译单元,编译器会扫描Assets文件夹下的所有.cs文件,自动建立内部符号表,无需显式声明依赖。
3. IDE的智能支持
• IntelliSense与实时分析
VS的IntelliSense会实时分析项目结构,即使未添加using语句,也会提示可用类(但编译时需满足命名空间或引用条件)。这种动态提示让开发者误以为“无需导入”,实际是IDE的辅助功能。
• 隐式引用Unity核心库
Unity自动为所有脚本引用UnityEngine、System等核心程序集,因此大部分基础类(如MonoBehaviour)可直接使用。
4. 与C++头文件机制的对比
特性 C++(需头文件) C#/Unity(无需头文件)
接口声明 需在.h文件中显式声明类/函数 类定义即接口,直接可见
编译单元 每个.cpp独立编译,依赖头文件合并 全局编译,自动解析所有脚本
依赖管理 手动#include路径或预编译头 项目引用或程序集自动关联
跨文件访问 需头文件声明+实现分离 类定义完整即可直接使用
5. 特殊情况处理
• 跨项目引用:若类位于不同程序集(如自定义DLL),需在Unity中通过Plugins文件夹引入DLL或配置mcs.rsp文件(仅限.NET 4.x API级别)。
• 命名空间冲突:需通过完整限定名(如NamespaceA.ClassX)或显式using解决。
总结
C#的设计和Unity的工程管理机制消除了显式头文件的需求,通过命名空间、程序集引用和全局编译实现了类之间的无缝访问。这种设计简化了开发流程,但开发者仍需注意命名空间管理和外部依赖的显式引用(如DLL)。
游戏设计的 What Why How
what目标是什么:游戏的目标
why 为什么玩家愿意去找目标:奖励机制
how:如何实现 对玩家的进程设置障碍 伴随奖励 对后续保持好奇心
项目
加入每打一球的评分机制?
加入一些教程
加入单人模式?
基础模式
超级模式?
模仿olo soccer 可以做中心得分制度 可以幸运大转盘 可以设计奖励金机制 可以有特别技能