Unity记录6.2-动作-角色生成
汇总:Unity 记录
摘要:角色生成的实现,包括生成后切换控制对象。
预制体加载-2023/09/26
- 和tile的加载类似,先加载总的配置文件,然后再分别加载各预制体。
- 目前是启动游戏时就异步加载所有预制体。
- 下面是加载代码。
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using Cysharp.Threading.Tasks;
public struct ObjectInfo{
public string ID;
public string name;
public string description;
public string path;
}
public struct ObjectsInfo{
public string version;
public Dictionary<string, ObjectInfo> objects;
}
public class ObjectList{
GameConfigs _game_configs;
ObjectsInfo _objects_info;
public Dictionary<string, GameObject> _name2object = new();
public Dictionary<string, string> _ID2objectName = new();
public ObjectList(GameConfigs game_configs){
_game_configs = game_configs;
load_objects();
}
public GameObject _load_object_by_name(string name){
return _name2object[name];
}
async UniTaskVoid load_object(string name){
string object_path = _objects_info.objects[name].path;
AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>(object_path);
handle.Completed += action_prefab_loaded;
await UniTask.Yield();
}
void load_objects(){
string objects_info_path = _game_configs.__objectsInfo_path__;
string jsonText = File.ReadAllText(objects_info_path);
_objects_info = JsonConvert.DeserializeObject<ObjectsInfo>(jsonText);
_ID2objectName.Add("0", "");
foreach (var object_kv in _objects_info.objects){
_ID2objectName.Add(object_kv.Value.ID, object_kv.Key);
load_object(object_kv.Key).Forget();
}
}
void action_prefab_loaded(AsyncOperationHandle<GameObject> handle){
if (handle.Status == AsyncOperationStatus.Succeeded) _name2object.Add(handle.Result.name, handle.Result);
else Debug.LogError("Failed to load prefab: " + handle.DebugName);
Addressables.Release(handle);
}
}
- 下面是配置文件
{
"version": "0.0.1",
"objects":{
"test ammo":{
"ID": 1,
"name": "test ammo",
"description": "",
"path": "Assets/Resources_addressable/Prefab/Objects/test ammo.prefab"
}
}
}
角色生成-2023/09/26
- 比较朴素,点击右键,生成角色。
public void _down_fire2(Vector2 mouse_pos){
_instantiate("test ammo", mouse_pos);
}
public void _instantiate(string name, Vector2 position){
GameObject obj = _object_list._name2object[name];
Instantiate(obj, position, Quaternion.identity);
}
游戏角色生成-2023/09/26-2023/09/30
- 为了生成能够操作的游戏角色,需要将控制系统,从原先指定好游戏角色,改为从某地查询游戏角色。
- 然后,在生成游戏角色的时候对应更新某地的游戏角色。
- 而这个某地,在被更改角色的时候,还要同时修改相机跟踪。
- 而上一步实际上并不难,只是修修改改而已,唯一的困难在于,落地就无法移动。
- 我试了多种方式,更改速度,加力,换调用刚体的方式,用正常的脚本调用异常脚本,用异常脚本调用正常脚本,等等等等,搞了五天,才搞定。
- 正常脚本是半年前写的,需要重构的脚本,但他可以正常运行。而异常的,则是我几天前测试正常,在更换调用方式后异常的脚本。
- 而第五天我是咋解决的呢?我没解决,它莫名其妙就好了。无法理解。无法理解。
- 这段时间,我把tilemap的addressable加载搞出来了,已对应更新:Unity记录4.1-存储-根据关键字加载Tile。
- 把所有代码和资源都从"Resources"迁移到"Resources_addressable"目录了。
- 还要七七八八和本项目无关的,不应该在这里提的,我都搞定了。
- 结果居然莫名其妙就好了。
- 回到主题。和之前提到的一样,在判断该角色是否属于游戏角色时,通过tag来判断。
- 移动脚本:
public void _move(Vector2 direction, float force, bool isInstant=false){
Vector2 force_speed = direction * force;
if (!isInstant) { // such as player move
Vector2 final_speed = new() {
x = _restrict_value_by_ori_max_change(_config._rb.velocity.x, _config._max_move_speed.x, force_speed.x),
y = _restrict_value_by_ori_max_change(_config._rb.velocity.y, _config._max_move_speed.y, force_speed.y)
};
Vector2 final_force = new(){
x = (final_speed.x - _config._rb.velocity.x) * _config._rb.mass / Time.fixedDeltaTime,
y = (final_speed.y - _config._rb.velocity.y) * _config._rb.mass / Time.fixedDeltaTime
};
_config._rb.AddForce(final_force, ForceMode2D.Force);
Debug.Log("final_speed: " + final_speed + "final_force: " + final_force + "force_speed" + force_speed);
} else {// such as player jump or be blown up
_config._rb.AddForce(force_speed, ForceMode2D.Impulse);
}
}
float _restrict_value_by_ori_max_change(float v_ori, float v_max, float v_ch){
if (Mathf.Abs(v_ori + v_ch) <= v_max) return v_ori + v_ch;
int dir_ori = v_ori > 0 ? 1 : -1;
if (v_ori * dir_ori > v_max) return (v_ch * dir_ori >= 0) ? v_ori : v_ori + v_ch / 10;
else return dir_ori * v_max;
}
- 生成角色时设定tags,_info内有tags。
public void _instantiate(string name, Vector2 position){
GameObject obj = _object_list._name2object[name];
obj = UnityEngine.Object.Instantiate(obj, position, Quaternion.identity);
obj.GetComponent<ObjectIndividual>()._info = _object_list._objects_info.objects[name];
}
- 控制角色的tags。
void init_action(){
List<string> identity = _config._tags.identity;
// ---------- action init ----------
if (identity.Contains("player")) action_player();
// ---------- action default ----------
}
void action_player(){
ControlSystem con = _config._hierarchy_search._searchInit<ControlSystem>("System");
con._set_player(_config._self);
}
- 前面提到的用于指定控制角色的某地。
public class ControlSystem : MonoBehaviour{
HierarchySearch _hierarchy_search;
public GameObject _player;
void Start(){
_hierarchy_search = GameObject.Find("System").GetComponent<HierarchySearch>();
}
void Update(){
}
public void _set_player(GameObject player){
_player = player;
_hierarchy_search._searchInit<CinemachineVirtualCamera>("Camera", "Player Camera").Follow = _player.transform;
}
}
文章目录
关闭
共有 0 条评论