您的位置:首页 > 健康 > 美食 > 建设工程合同纠纷起诉状_页面设计读书笔记1500_长沙百度快速排名_网站seo在线诊断

建设工程合同纠纷起诉状_页面设计读书笔记1500_长沙百度快速排名_网站seo在线诊断

2024/10/7 6:44:41 来源:https://blog.csdn.net/m0_73087695/article/details/142456698  浏览:    关键词:建设工程合同纠纷起诉状_页面设计读书笔记1500_长沙百度快速排名_网站seo在线诊断
建设工程合同纠纷起诉状_页面设计读书笔记1500_长沙百度快速排名_网站seo在线诊断

前言

        说起来,Unity的社区环境跟插件支持确实要比Godot好很多,比如我们Unity最喜欢的Cinemachine插件,只需要动动手指就能轻松实现很多高级的摄像机动效。

        所以一转到Godot就有一种力不从心的感觉,于是既然动不了手指我们就动手。自己做一个想要的摄像机。

        Godot版本:4.3 mono

思路

        其实没什么好说的,一开始只是想做一个能跟着某个节点移动的摄像机,至于为什么不直接把摄像机作为被跟随节点的子节点呢?因为Godot中的摄像机是按照节点树层次找到并展示最近的一个父级Viewport的,我觉得如果一个场景中有多个摄像机的情况,再加上被跟随节点自带的摄像机可能就不好管理了。还有用Unity习惯了,就这样考虑了。

        人都是贪得无厌的,一开始还是只想做一个跟随就好了,结果为了满足自己的奇葩需求,索性就加了一些其他功能。

源码   

using System.Collections;
using Godot;namespace GoDogKit
{/// <summary>/// A highly customizable camera that automatically follows a target./// </summary>public partial class AutoCamera2D : Camera2D{/// <summary>/// The target to follow./// </summary>[Export] public Node2D FollowTarget { get; set; } = null;/// <summary>/// Defines the maximum distance from the target to follow. Does not effect to the predict behaviour./// </summary>[Export] public float FollowClamp { get; set; } = 1.0f;/// <summary>/// Defines the camera's behaviour when following the target./// </summary>public enum BehaviourType{/// <summary>/// Follows the target normally. Results in global position copying./// </summary>Normal,/// <summary>/// Smoothly follows the target in a given duration. Results in global position interpolation./// </summary>            Inching,/// <summary>/// Follow the target with a constant speed. It can be faster or slower than the target's speed./// If the follow speed equals or exceeds the target's speed, results just like the Normal behaviour./// If the follow speed is slower than the target's speed, the camera will/// be clamped within a given distance from the target aka max distance./// </summary>            Slow,/// <summary>/// Follow the target with predictive behaviour./// It predicts the target's movement based on its last position./// And moves the camera towards the predicted position which /// determined by predict distance with a constant speed./// </summary>Predict}[Export] public BehaviourType Behaviour { get; set; } = BehaviourType.Normal;[ExportGroup("Inching Properties")][Export]public float InchingDuration{get => m_inchingDuration;set => m_inchingDuration = value;}private float m_inchingDuration = 1.0f;private float m_inchingTimer = 0.0f;[ExportGroup("Slow Properties")][Export] public float SlowFollowSpeed { get; set; } = 100.0f;[Export] public float SlowFollowMaxDistance { get; set; } = 100.0f;[ExportGroup("Predict Properties")][Export] public float PredictFollowSpeed { get; set; } = 100.0f;[Export] public float PredictDistance { get; set; } = 100.0f;private Vector2 m_targetLastPos = Vector2.Zero;public override void _Ready(){m_inchingTimer = m_inchingDuration;m_targetLastPos = Vector2.Zero;}private void NormalFollow(double delta){GlobalPosition = FollowTarget.GlobalPosition;}private void InchingFollow(double delta){float distance = GlobalPosition.DistanceTo(FollowTarget.GlobalPosition);// If the target is too close, stop inching.if (distance < FollowClamp){m_inchingTimer = m_inchingDuration;return;}m_inchingTimer -= (float)delta;// If the inching timer has reached 0, reset it and start inching again.float rate = m_inchingTimer <= 0.0f ? 1.0f : 1.0f - m_inchingTimer / m_inchingDuration;var _x = Mathf.Lerp(GlobalPosition.X, FollowTarget.GlobalPosition.X, rate);var _y = Mathf.Lerp(GlobalPosition.Y, FollowTarget.GlobalPosition.Y, rate);GlobalPosition = new Vector2(_x, _y);}private void SlowFollow(double delta){float distance = GlobalPosition.DistanceTo(FollowTarget.GlobalPosition);// If the target is too close, stop following.if (distance < FollowClamp){return;}// If the target is too far, move it to max distance position.if (distance > SlowFollowMaxDistance){Vector2 distanceVec = (FollowTarget.GlobalPosition - GlobalPosition).Normalized() * SlowFollowMaxDistance;GlobalPosition = FollowTarget.GlobalPosition - distanceVec;return;}var _x = Mathf.MoveToward(GlobalPosition.X, FollowTarget.GlobalPosition.X, (float)delta * SlowFollowSpeed);var _y = Mathf.MoveToward(GlobalPosition.Y, FollowTarget.GlobalPosition.Y, (float)delta * SlowFollowSpeed);GlobalPosition = new Vector2(_x, _y);}private void PredictFollow(double delta){// Predict the direction of the target based on its last position.Vector2 predictedDir = (FollowTarget.GlobalPosition - m_targetLastPos).Normalized();Vector2 predictedPos = FollowTarget.GlobalPosition + predictedDir * PredictDistance;var _x = Mathf.MoveToward(GlobalPosition.X, predictedPos.X, (float)delta * PredictFollowSpeed);var _y = Mathf.MoveToward(GlobalPosition.Y, predictedPos.Y, (float)delta * PredictFollowSpeed);GlobalPosition = new Vector2(_x, _y);// Record the last position of the target for the next prediction.m_targetLastPos = FollowTarget.GlobalPosition;}       public override void _PhysicsProcess(double delta){// If there is no target, do nothing.if (FollowTarget == null) return;switch (Behaviour){case BehaviourType.Normal: NormalFollow(delta); break;case BehaviourType.Inching: InchingFollow(delta); break;case BehaviourType.Slow: SlowFollow(delta); break;case BehaviourType.Predict: PredictFollow(delta); break;}}}
}

           其实结构还是非常简单明了的(因为我也写不出很复杂的东西)。通过预设值决定摄像机的具体行为逻辑,就是这么简单。

        哦对了,Godot的2D和3D的区别跟Unity不一样,Unity的2D是伪2D,而Godot的2D是真2D,

所以2D跟3D之间的沟壑可能比Unity大。所以我先做了2D的相机。

        这个的操作方式应该跟Unity的差不多,就是调整数值还有选模式。主要这些模式都是我硬编的,其实我也不知道应该怎么为这些模式命名:

        1.Normal,普通行为,就一直跟着,其实就是复制位置。

        2.Inching,我管它叫缓动,从代码可以看出,这玩意跟时间有关,设计之初是想实现“在规定时间结束时,镜头恰好到达物体位置”,结构因为插值插的太快了,所以只能看出一点点效果,所以之后应该会大改或者直接砍掉;

        3.Slow,慢跟随。其实也可以快,通过控制跟随速度营造出“镜头和物体相对运动的效果”。

实际上镜头跟随太慢会被限制在一个距离内,从而避免物体跑太快了以至于跑出镜头外。

            // If the target is too far, move it to max distance position.

            if (distance > SlowFollowMaxDistance)

            {

                Vector2 distanceVec = (FollowTarget.GlobalPosition -                 GlobalPosition).Normalized() * SlowFollowMaxDistance;

                GlobalPosition = FollowTarget.GlobalPosition - distanceVec;

                return;

            }

        限制手段就是这个:当相对距离超过限定距离时,根据等式关系减去偏移量。

        为什么要单独拿出来记录呢?因为我之前写那个Untiy卡牌拖拽模型的时候,就是遇到了这种“锁定偏移量”的类似问题,当时还强调了一下,结果现在做开发的时候又又又错了。

        4.Predict,预测跟随。这个比较有意思,我忘了Cinemachine有没有,印象中好像就是没有的。因为感觉很多游戏都会有这么一个“根据玩家移动方向适当移动镜头”的操作,那么我也尽量用自己的手段实现:很简单,根据上下帧得出运动方向的预测值,然后朝那个方向运动预设的一段距离。

        然后其实没什么了,我记得Cinemachine可以设置帧处理方式,比如Update和FixedUpdate,但是在这里我就索性扔到物理帧处理中了。

        所谓的什么模式,只是打开一个DIY思路,后面有什么需求再自己修改就好了。

结语

        这里不得不提一嘴,Godot开发插件的方式真的极其简单,基本上直接把源码拿进去就行,所以我索性就把学习开发过程中造的轮子搞成一堆插件扔在Github上了,这几天Unity转Godot就一直在更新:

MOWEIII/GoDogKit: A Plugin kit used by Godot which personally used and maybe continue to be update. (github.com)icon-default.png?t=O83Ahttps://github.com/MOWEIII/GoDogKit

        有需要的同志可以看看,虽然我的水平很低就是了。

摄像机震动???

        我在Unity开发中曾做个一个相机震动的效果,就很简单的在一个圆形范围内随机点,赋值给摄像机位置,只要频率够快,就能模拟出震动效果。

        虽然逻辑简单,但处理起来还要考虑很多东西,如果用Timer的方式(就是声明计时用的一堆变量)就需要很复杂的启动逻辑和变量管理。幸好Unity为我们提供了协程,我们可以轻松实现延迟和计时等等。

        那么问题来了,Godot C# 也没有协程啊(GDScript好像有)。那没办法了,只能自己做去罢。结果这一做不得了,又发现很多好玩的东西。留到下一章单独细说吧。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com