Godot游戏练习01-第11节-显示优化,游戏背景,Shader

0 阅读3分钟

现在基础的机制和功能都有了, 是时候来优化一下游戏的显示效果了, 截止到上次开发, Player还不会转向, 并且武器在旋转时还会倒过来, 比较违和

今天来统一优化

优化后的效果

  1. 处理了游戏中的人物与武器转向
  2. 实现了一个动态的游戏背景, 使用简单Shader

动画7.gif

实现思路

人物与武器的翻转

只有一个关键操作: 将人物的Sprite2D与武器部分的scale, 依据鼠标指向方位设置为(-1, 0)或者(1, 0), 也就是x轴的翻转

func _update_aim_direction() -> void:
	var aim_vector := player_input_multiplayer_synchronizer_component.aim_vector
	visual_root.scale = Vector2.ONE if aim_vector.x >= 0 else Vector2(-1.0, 1.0)
	weapon_root.look_at(weapon_root.global_position + aim_vector)

也就是上述源码中的visual_root部分

visual_root是Player场景中新增的Node2D, 作为Player自身Sprite2D与WeaponRoot节点的父节点, 方便统一实现x轴的scale翻转

这里要注意一个细节:

WeaponRoot相对于visual_root的x位置必须为0, 因为我们的aim_vector的计算是计算aim_root节点到鼠标指向位置的方向向量, 而Player中给aim_root关联的节点正是WeaponRoot

若WeaponRoot相对于visual_root的x大于0, 当鼠标指向正下方时, 计算的aim_vector的x会小于0, 在上述逻辑中会自动将scale设置为(-1, 1), visual_root整体的x轴翻转, 翻转后, WeaponRoot的方位发生了变化, 下一帧计算的aim_vector的x又大于0, 如此循环, 会在每一帧中循环翻转, 直接鬼畜

因此应当保持WeaponRoot的相对位置为0, 发生翻转后, 其global_x不要发生变化, 避免导致aim_vector突变

背景的实现与简单Shader

原始的背景Texture很简单, 一个256x256的格子图

Sprite-0006.png

实现动态背景的几个步骤

  1. Texture重复, 默认是不打开的, 可以在Sprite2D的信息面板中 CanvasItem -> Texture -> Repeat 修改为 Enabled, 之后打开Sprite2D的region选项, 调整width和height, 超出原始Texture大小的部分就会不断重复, 得到一张无限大的格子图

  2. 将Sprite2D格子图稍加旋转, 调整格子图大小, 在旋转后能覆盖设计尺寸即可

  3. 在Sprite2D上添加Material -> ShaderMaterial, 绑定shader脚本, 内容如下

    shader_type canvas_item;
    
    void fragment() {
    	// Called for every pixel the material is visible on.
    	vec4 color = texture(TEXTURE, UV + vec2(TIME * -0.032, TIME * -0.045));
    	COLOR = color;
    }
    

    按照惯例, 我们只了解Shader中的必要内容, 能完成本次内容即可

    • shader是Godot渲染时会调用的代码, fragment(片元着色器), Godot在渲染每个像素时都会调用, 它的默认注释也说明了作用
    • TEXTURE TIME UV COLOR 是shader中的内置变量, 分别表示 当前使用的纹理; 当前的时间(线性增加); 当前正在渲染的像素相对坐标vec2, 两个维度值在(0.0-1.0)之间; 最终输出的颜色
    • texture函数是从第一个纹理参数中取出位于第二个坐标参数处的颜色, 若坐标值超出0-1的范围, 则循环处理
    • 源码中的操作是: 在当前的渲染坐标UV上加上时间量TIME一定比例的偏移, 将偏移的颜色作为最终颜色输出

    由于时间量会不断增加, 因此渲染出来的颜色也是不断偏移之后的颜色, 最终看到的效果就是背景画面在不断移动

最后将这个动态背景Sprite2D设置为Autoload节点, 默认加载, 在主菜单和游戏场景都生效

image.png