自由学习记录(18)

news2024/11/5 8:49:39

动画事件的碰撞器触发

Physics 类的常用方法

RaycastHit hit;
if (Physics.Raycast(origin, direction, out hit, maxDistance)) {
    Debug.Log("Hit: " + hit.collider.name);
}

Physics.Raycast:从指定点向某个方向发射射线,检测是否与碰撞体相交。

Physics.RaycastAll:发射射线并返回所有碰撞到的对象

 Physics.IgnoreCollision:忽略两个碰撞体之间的碰撞。

Physics.IgnoreCollision 方法可以用来忽略两个碰撞体之间的碰撞,但它并没有直接提供查看已忽略碰撞的功能。

如果你需要跟踪哪些碰撞体之间的碰撞被忽略,可以考虑手动维护一个列表或字典,用于记录哪些碰撞体之间的碰撞被忽略。你可以在调用 Physics.IgnoreCollision 时,将被忽略的碰撞体记录到这个列表中。

Dictionary<Collider, List<Collider>> ignoredCollisions = new Dictionary<Collider, List<Collider>>();

void IgnoreCollision(Collider a, Collider b) {
    Physics.IgnoreCollision(a, b);
    if (!ignoredCollisions.ContainsKey(a)) {
        ignoredCollisions[a] = new List<Collider>();
    }
    ignoredCollisions[a].Add(b);
}

额外的写法,搭配元组 绑定两个碰撞体之间的关系值

Dictionary<(Collider, Collider), bool> ignoreds = new Dictionary<(Collider, Collider), bool>();

void IgnoreCollision(Collider a, Collider b) {
    Physics.IgnoreCollision(a, b);
    ignoreds[(a, b)] = true; // 记录忽略的碰撞
}

void LogIgnoreds() {
    foreach (var pair in ignoreds.Keys) {
        Debug.Log($"Ignored Collision: {pair.Item1.name} - {pair.Item2.name}");
    }
}

Dictionary<(Collider, Collider), bool> ignoredCollisions = new Dictionary<(Collider, Collider), bool>();

// 记录忽略的碰撞
ignoredCollisions[(colliderA, colliderB)] = true;

Physics.gravity:获取或设置全局重力向量,影响所有物体的重力效果。

只对于场景上附加了 Rigidbody 组件的物体,Physics.gravity 会直接影响它们的重力。默认情况下,Rigidbody 会根据这个全局重力向量施加重力。

Physics.DrawRay:用于在场景视图中可视化射线,便于调试。

帮助你可视化射线,确保其正确指向目标

public static void DrawRay(Vector3 start, Vector3 direction, Color color = Color.white, float duration = 0f);

 start (Vector3):射线起点

direction (Vector3):射线的方向,通常是一个单位向量

ps:Physics.DrawRay 实际上并没有直接提供长度参数,它只需要起点和方向向量。

要使用射线的长度,你通常需要将方向向量再乘以要的长度,然后计算出终点。

color (Color):射线的颜色,默认是白色。

Debug.DrawLine 可以绘制从 startend 的线,两者是有些区别的

Debug.DrawRay(start, direction, Color.red);

Physics.OverlapSphere

Collider[] Physics.OverlapSphere(Vector3 position, float radius, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);

返回一个 Collider 数组,包含所有在指定位置和半径内的碰撞体。

 position (Vector3):球体中心的位置,表示检测的起始点。

radius (float):球体的半径,决定了检测的范围。

layerMask (int):可选参数,指定哪些层的碰撞体将被检测。默认为所有层。通过位掩码可以更精确地选择层。

queryTriggerInteraction (QueryTriggerInteraction):可选参数,指定是否检测触发器(Trigger)。可以选择以下值:

  • QueryTriggerInteraction.UseGlobal:使用全局设置。
  • QueryTriggerInteraction.Ignore:忽略触发器。
  • QueryTriggerInteraction.Collide:包括触发器。
void Update() {
    // 定义球体中心和半径
    Vector3 sphereCenter = transform.position;
    float sphereRadius = 5f;

    // 获取在范围内的碰撞体
    Collider[] hitColliders = Physics.OverlapSphere(sphereCenter, sphereRadius);

    // 遍历所有碰撞体
    foreach (Collider collider in hitColliders) {
        // 输出碰撞体的名称
        Debug.Log("Detected: " + collider.name);
    }
}

拾取物品、感知范围、区域触发事件 

摄像机移动的四元数

只传入一个方向向量给 Quaternion.LookRotation 时,它会默认使用世界坐标系的 Y 轴(即上方向)作为“上”方向。

如果你希望更好地控制对象的朝向和倾斜,可以传入第二个参数,指定一个自定义的上方向

Vector3 direction = new Vector3(1, 0, 0);
Vector3 up = Vector3.up; // 指定上方向为 Y 轴正方向
Quaternion targetRotation = Quaternion.LookRotation(direction, up);

 意思是第一个向量确定xz面,上方向再加上y的确认,达成四元数

摄像机的跟随

游戏资源的关系梳理

写代码的时候更带一点编程人员的角度,可拓展性有时也会提高,比如对血条的控制,在这里,maxhp也同样加入了可以控制的范围,看上去多传入了一个参数可能会麻烦一点,不够简化,

但是多传入一个参数的性能消耗其实并不高,如果考虑到游戏制作流程的人力资源分配,则是小巫见大巫

细节之处的地方没有必要那么省性能,影响开发速度

对于做一个流程的游戏,如果过多把写了的东西揉成一团丢一边,然后重写,追求更好的写法,这样也不利于写联通的逻辑。

需要实现功能时,减少性能或优雅追求的妥协点,毕竟需要的功能之后再加上也是可以的,不需要的功能后面要砍也是可以的,而同一个功能的反复修改,可能会有一些得不偿失

gizmo如果没有打开,看不到寻路烘焙

需要注意的是,在unity开发中的“资源自带区”,完全不仅仅是只能看做对资源的提供,还有对变化数据资源的提供再提供,意思是同样的一份数据,可以仅仅是一存一拿,也可以是存入,被其他的拿去计算后,再拿回,

如装备的数据,但这只是很浅一部分,里面记录了很多游戏内容相关的东西,然后这些“游戏内容承载体”可让玩家的可操作数据因此发生二次变化,一种不属于物理操作本身的额外游戏内容数据变化

ps:物理操作本身给出的变化,称为一次变化,这种变化是固定的,与游戏额外添加内容无关的

将资源区的数据分为游戏本身自带的“资源自带区”,和玩家操作产生变化的区域

玩家操作产生变化的区域,

再分成如音乐大小设置,画质帧率设置,操作界面调整等偏后台类数据记录

和玩家操作过程中时常变动的数据,比如血量等级,经验值,装备穿戴情况(装备情况由 “资源自带区”提供,参与计算并给定最终对角色的影响)

资源的使用和游戏物体的预设使用,资源是直接可以套上组件,游戏对象的使用是对资源区的物体,执行实例化的方法

物体的删除和创建没有想象的那么耗性能,并不是说可以完全不要去注意,只是不要放过多权重在上面

SQL视图和索引

MySQL 视图(View)是一个虚拟表,它是基于 SQL 查询的结果集。视图并不存储数据本身,而是存储了一个 SQL 查询的定义。

CREATE VIEW order_summary AS
SELECT 
    order_id,
    customer_id,
    order_date,
    total_amount
FROM 
    orders;

现在,可以简单地查询视图,SELECT * FROM order_summary;

视图可以将复杂的查询逻辑封装在一个简单的结构中。这样,你可以用一个简单的 SELECT 语句来替代复杂的 SQL 查询,降低了使用的复杂性。

视图可以被设计为可更新的,例如,如果你有一个简单的视图只选择了单个表的所有列,那么你可以通过视图进行数据更新,并且更新会直接影响基础表的对应记录。

UPDATE order_summary SET total_amount = 150.00 WHERE order_id = 1;

使用视图可以限制用户的访问权限。例如,如果你希望用户只能访问订单的摘要信息而不允许访问原始表中的其他敏感信息,可以创建一个视图,只包含所需的字段

非聚集索引是一种用于提高数据库查询性能的重要工具。它通过创建独立的索引结构,使得对表中特定列的查询更加高效。

如果没有索引,数据库需要扫描整个表以找到匹配的行;而有了 idx_department 索引后,查询会更快,因为数据库可以直接访问相关的索引数据。

SELECT * FROM employees WHERE department = 'Sales' AND salary > 50000;

如果 id 是主键,它会自动成为聚集索引。

父子预设体的问题

UI的子物体的预设体设置

Image 的 RectTransform 会记录其相对于 Canvas 的位置、锚点、大小等信息。当你在 Canvas 下创建 Image 时,这些属性都是相对于该 Canvas 的。

如果将 Image 预设体拖放到不同大小的 Canvas 上,由于其属性是相对原始 Canvas 的,所以会出现问题

位置偏移:由于不同 Canvas 的尺寸和锚点设置,Image 可能不会在新 Canvas 中显示在预期的位置。

缩放问题:如果原始 Canvas 和目标 Canvas 的缩放比例不同,Image 的大小和显示效果可能也会受到影响。

正常 的3d父子物体,子物体设置成预设体也是记录相对父物体的信息

子物体的 Transform 会记录相对于父物体的位置信息(localPosition)、旋转信息(localRotation)和缩放信息(localScale)。这意味着无论父物体的位置和旋转如何变化,子物体的相对位置和旋转关系保持不变。

如果没有父物体,则默认把这些相对的值赋到世界坐标系上

相对值:没有父物体的情况下,GameObject 的 localPositionlocalRotationlocalScale 的值会直接对应于它的 positionrotationscale。这意味着:

  • localPosition 等于 position
  • localRotation 等于 rotation
  • localScale 等于 scale

当你将一个没有父物体的 GameObject 作为预设体存储并实例化时,它将出现在场景中的确切位置(相对于世界坐标系),并且其 Transform 信息不会受到其他物体的影响。

动画设置总结

串面板的实现,一定会存在初逻辑做的差不多之后发现有小问题没有统一的解决,

对于这种做的快完的时候发生的优化问题,如果想要完全避免的话,

思考成本很高,而且自己的功能实现能力也许会受限

而且一般来讲,这种问题都是边边角角的,如果需要额外加也是可以的

状态机的override版本一定是有用的,给的资源,角色拿着不同武器的移动方式,攻击方式是可归类的,

状态机合理利用override的话,应该说是对角色所有动作的构成和融合的归类,因为有blend tree

移动相关的设置可以更加概括成一个状态,

向前,后,左,右四个动作,构成一个blend tree 进行融合,并且用animator的参数管控blend的2d融合参数,

然后攻击动画只影响上半身,于是利用了遮罩的设置,先建立新的动画层,权重拉高,然后把下半身全部mask,触发开火的时候就可以只变化上半身,但这个新层要注意做一个空状态,不然有点没起点的感觉

对于下蹲,则是又开一层,但这一层开启sync同步,并贴在移动的基层上

之后通过new Layer的权重增大,从而达到让角色下蹲的样子

状态机的设置,可以在内部实现把移动的代码相关调控问题直接解决,给外部仅仅提供一个x和y值和触发的状态,就可以达成预期效果

Animator状态机的要点

层的同步

层的权重设置

层的遮罩不处理

层的参数外提供

状态的连接建立

参数对状态切换的调控

子状态机

右击子状态机或其他状态,选择 "Make Transition" 来创建过渡。

进入子状态机后,会进行独立的状态逻辑判断。子状态机内部可以有自己的状态、过渡和条件,这些都是独立于主状态机的。

可以把子状态机当成状态机的递归,在最上层的状态结构里,子状态机就是一个正常节点,但是如果过渡到该节点之后,就会变成在该子状态机了进行全新的条件判断

摄像机的动画设置

准确来说,有时候代码简化反而可能不如不简化直接使用,比如这里,很直接的把动画播放结束的事件分割成了一个只写了一点点代码的函数,看上去的确是可以简化,反正需要的效果也不多

但如果要简化,很容易把函数结束的一种逻辑潜意识也混入了左转右转的两个动画里,这对于保持逻辑清晰来说,简化后并不一定真的有简化,也许现在看不出什么问题,但有些问题会自然的带到后面对功能的开发

这里更像是动态添加事件函数,每次点击传入这段函数,然后转到动画事件部分,通过将传过来的时间,丢入一个事件变量,然后由PlayOver统一执行这个事件

这样的好处,首先的确是很清爽,如果想自己换法子实现,就要比较复杂的实现延时执行面板的显隐。

动画事件串联全程 

 添加之后会去脚本里面找

这个函数是写在挂在CameraAnimator这个自定义的脚本上的

动画事件那一块是可以检测到并使用的

动画完成之后要做什么操作,这里是设置了私有变量,以达到外部传入操作到Camera,Camera可以执行该操作

最后就是给外部调用的两个turn的函数,外部尽管传入操作,Camera内部会接收,先执行转向的动画,animator.SetTrigger("具体的对应状态");

然后Animatior就会进入动画的播放,而左转右转这两个自己编辑出来的动画,也对应的在播放结束的位置加上了动画事件,则是PlayOver

而此时,由于触发时间的不同,点击左转时,调用了左转的函数,

先是触发了左转动画的播放,然后立刻给动画播放完成之后 那个存储动画事件的变量添加了要执行的操作,等到旋转动画播放完,就执行那个存储的PlayOver函数,执行完之后再置空保证优雅

Animation Event

public void PlaySound(float volume)
{
    Debug.Log($"Playing sound at volume: {volume}");
}

挂载到该 GameObject 的 MonoBehaviour 脚本中定义。被调用的函数必须是 public 的。

Animation Event 中,还可以用带参数的函数,难免就会有疑惑,因为方法是写成这样,而调用传参的权利不在自己而在Animation event上。

参数值是由你在 Animation Event 的设置面板中直接定义的,在参数字段中,输入你想要传递给 volume 的具体值,比如 1.0。这就是你在 Animation Event 中设置的参数值,是你当场定义当场用的感觉,

参数并不是自动从其他地方传递的,而是通过你在 Animation Event 中配置的内容直接给定的。。

背景音乐设置

使用UImanager来管理面板的显隐

GameDataMgr来统一管理数据的存储

音乐脚本设置为单例,强调只需要一个来管理就够了

节约性能,虽然实时在改变拖动的值,但是并没有存在musicdata里面,在点击叉之后再一次性存入Gamedatamgr

每次滑动都直接修改音量上的值,和游戏数据管理类里的直接值,那这里的SaveMusicData

意味着存入json?是的,毕竟内存和硬盘看似很接近,实则天差地别,两个完全不属于一个世界

从硬盘里通过json读过来的数据,到了内存里就和之前毫无联系了,

只有内存呼唤json,建立联系,才能把内存的数据再输入给硬盘

对于背景音乐,设置一个场景上的对象,再挂载对应的脚本,管理上面的各种声音

数据管理类的单例,首次调用时引发构造函数,构造函数中导入json数据

而音乐对象身上的awake里,则调用游戏管理数据类获取音乐设置数据

Life is an absurd art.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2231510.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[FE] React 初窥门径(四):React 组件的加载过程(render 阶段)

1. 回顾 前几篇文章中&#xff0c;我们采用了 VSCode 插件 CodeTour 来记录代码的执行过程&#xff0c; 并把相关的数据 .tour/ 放到了 github: thzt/react-tour 中。 截止到本文为之&#xff0c;我们总共记录了这些 code-tour&#xff0c; .tour/ ├── 2. 构建过程.tour ├─…

java毕业设计之基于Bootstrap的常州地方旅游管理系统的设计与实现(springboot)

项目简介 基于Bootstrap的常州地方旅游管理系统的设计与实现有下功能&#xff1a; 基于Bootstrap的常州地方旅游管理系统的设计与实现的主要使用者分为用户功能模块和管理员功能模块两大部分&#xff0c;用户可查看景点信息、景点资讯等&#xff0c;注册登录后可进行景点订票…

单链表OJ题(3):合并两个有序链表、链表分割、链表的回文结构

目录 一、合并两个有序链表 二、链表分割 三、链表的回文结构 u解题的总体思路&#xff1a; 合并两个有序链表&#xff1a;首先创建新链表的头节点&#xff08;哨兵位&#xff1a;本质上是占位子&#xff09;&#xff0c;为了减少一些判断情况&#xff0c;简化操作。然后我们…

为数据集而生的 SQL 控制台

随着数据集的使用量急剧增加&#xff0c;Hugging Face 社区已经变成了众多数据集默认存放的仓库。每月&#xff0c;海量数据集被上传到社区&#xff0c;这些数据集亟需有效的查询、过滤和发现。 Dataset Monthly Creations 每个月在 Hugging Face Hub 创建的数据集 我们现在非常…

简易了解Pytorch中的@ 和 * 运算符(附Demo)

目录 1. 基本知识2. 3. * 1. 基本知识 在 PyTorch 中&#xff0c; 和 * 运算符用于不同类型的数学运算&#xff0c;具体是矩阵乘法和逐元素乘法 基本知识 运算符功能适用场景示例矩阵乘法&#xff08;或点乘&#xff09;用于执行线性代数中的矩阵乘法C A B&#xff0c;其中…

JavaScript知识点梳理及案例实践

1. Date对象 创建Date对象 //方法1&#xff1a;不指定参数 var nowd1new Date(); console.log(nowd1.toLocaleString( )); //方法2&#xff1a;参数为日期字符串 var d2new Date("2004/3/20 11:12"); console.log(d2.toLocaleString( )); var d3new Date("04/…

推荐一款Windows维护和修复工具包:RepairKit

RepairKit是一个综合性的Java开发的Windows修复和维护工具包。该工具包旨在为用户提供一个专用的系统修复工具&#xff0c;并快速访问一些操作系统功能及其他附带的电脑维护软件。 RepairKit 提供了一个简单有效的解决方案&#xff0c;用于维护PC的顺畅运行。它包括自动修复/清…

cocos开发QA

目录 TS相关foreach循环中使用return循环延迟动态获取类属性 Cocos相关属性检查器添加Enum属性实现不规则点击区域使用cc.RevoluteJoint的enable激活组件无效本地存储以及相关问题JSON.stringify(map)返回{}数据加密客户端复制文本使用客户端方法热更新LabelOutline.color is d…

大数据新视界 -- 大数据大厂之 Impala 性能优化:数据存储分区的艺术与实践(下)(2/30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

记第一次本地编译seatunnel源码

拉取代码 git clone https://github.com/apache/seatunnel.git 使用版本 我们生产环境用的是2.3.5版本&#xff0c;所以基于2.3.5-release分支代码进行编译。 maven package过程 遇到的第一个问题&#xff1a;‘com.sun.tools.javac.tree.JCTree com.sun.tools.javac.tree…

6.1、属性动画

使用显式动画产生布局更新动画 1.旋转动画 只修改对应的属性 rotate({angle: this.angle}) 即可达到效果 动画效果 对应实现代码 @Entry @Component struct AnimationPage {@State angle:number = 0aboutToAppear() {

串口屏控制的自动滑轨(未完工)

序言 疫情期间自己制作了一个自动滑轨&#xff0c;基于无线遥控的&#xff0c;但是整体太大了&#xff0c;非常不方便携带&#xff0c;所以重新设计了一个新的&#xff0c;以2020铝型材做导轨的滑轨&#xff0c;目前2020做滑轨已经很成熟了&#xff0c;配件也都非常便宜&#x…

Git在码云上的使用指南:从安装到推送远程仓库

目录 前言&#xff1a; 1、git的安装 1.1.Linux-centos环境下安装 1.2.Linux-ubuntu环境下安装 2.创建Git本地仓库 3.配置Git 4.认识⼯作区、暂存区、版本库 5.添加文件 5.1.git命令 5.2.commit命令 6.远程操作 6.1.新建远程仓库 6.2.克隆远程仓库&#xff1a; 6…

GESP4级考试语法知识(冒泡排序)

冒泡排序参考程序&#xff1a; #include <iostream> using namespace std; const int MAXN10001; int main() {int n,i,j;float a[MAXN];cin>>n;for(i1;i<n;i)cin>>a[i]; //输入n个数bool ok;for(in;i>1;i--){oktrue; //判断是…

无人机场景 - 目标检测数据集 - 夜间车辆检测数据集下载「包含VOC、COCO、YOLO三种格式」

数据集介绍&#xff1a;无人机场景夜间车辆检测数据集&#xff0c;真实场景高质量图片数据&#xff0c;涉及场景丰富&#xff0c;比如夜间无人机场景城市道路行驶车辆图片、夜间无人机场景城市道边停车车辆图片、夜间无人机场景停车场车辆图片、夜间无人机场景小区车辆图片、夜…

重学SpringBoot3-整合 Elasticsearch 8.x (一)客户端方式

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 这里写目录标题 1. 为什么选择 Elasticsearch&#xff1f;2. Spring Boot 3 和 Elasticsearch 8.x 的集成概述2.1 准备工作2.2 添加依赖 3. Elasticsearch 客户端配置方式…

动态规划应该如何学习?

动态规划如何学习 参考灵神的视频和题解做的笔记&#xff08;灵神YYDS&#xff0c;以后也都会用这套逻辑去思考&#xff09; 枚举选哪个&#xff1a; 动态规划入门&#xff1a;从记忆化搜索到递推_哔哩哔哩_bilibili 746. 使用最小花费爬楼梯 - 力扣&#xff08;LeetCode&a…

从零开始构建 ChatGPT

今天&#xff0c;我们要介绍的是一个名为 LLMs-from-scratch 的 GitHub 项目&#xff0c;它由开发者 rasbt 精心打造&#xff0c;旨在一步步教你如何使用 PyTorch 从零开始实现一个类似 ChatGPT 的大型语言模型&#xff08;LLM&#xff09;。 这是一个教育性质的开源项目&…

音视频听译:助力多维度沟通与发展的大门

在全球经济一体化的大背景下&#xff0c;企业之间的跨国合作愈发频繁。在商务会议、谈判和产品演示等活动中&#xff0c;语言的多样性成为了一大挑战。而音视频听译服务能够将不同语言的音频准确转换为目标语言文字&#xff0c;确保信息的精准传达&#xff0c;避免因语言障碍引…

向量模型Jina Embedding: 从v1到v3论文笔记

文章目录 Jina Embedding: 从v1到v3Jina Embedding v1数据集准备训练过程 Jina Embedding v2预训练修改版BERT在文本对上微调在Hard Negatives上微调 Jina Embedding v2 双语言预训练修改版BERT在文本对上微调用多任务目标微调 Jina Embedding v3预训练在文本对上微调训练任务相…