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;
    }
}

版权声明:
作者:MWHLS
链接:https://mwhls.top/4923.html
来源:无镣之涯
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
< <上一篇
下一篇>>
文章目录
关闭
目 录