修改OpenGl渲染底层之前
This commit is contained in:
@@ -36,6 +36,14 @@ void Chr_Animation::CreateSkinmationBySlot(std::string actionName, std::string s
|
||||
Ani->SetRenderZOrder(Variation.Layer);
|
||||
this->AddChild(Ani);
|
||||
ActionAnis[actionName].push_back(Ani);
|
||||
|
||||
// 构造一下阴影对象
|
||||
RefPtr<Animation> ShadowAni = new Animation(path, FormatImgPath, Data);
|
||||
ShadowAni->SetVisible(false);
|
||||
// 皮肤统一设置阴影
|
||||
ShadowAni->SetShadow();
|
||||
chr_parent->_Shadow->AddChild(ShadowAni);
|
||||
chr_parent->_Shadow->ActionAnis[actionName].push_back(ShadowAni);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,11 +114,7 @@ void Chr_Animation::SetAction(std::string actionName)
|
||||
Ani->SetVisible(true);
|
||||
}
|
||||
CurrentActionTag = actionName;
|
||||
}
|
||||
|
||||
void Chr_Animation::Update(float deltaTime)
|
||||
{
|
||||
RenderBase::Update(deltaTime);
|
||||
// SDL_Log("Position %d %d", this->GetTransform().position.x, this->GetTransform().position.y);
|
||||
// SDL_Log("IterPosition %d %d", this->GetIterationTransform().position.x, this->GetIterationTransform().position.y);
|
||||
// 设置阴影的动作
|
||||
chr_parent->_Shadow->SetAction(actionName);
|
||||
}
|
||||
|
||||
@@ -45,6 +45,4 @@ public:
|
||||
void Init(CharacterObject *parent);
|
||||
// 设置动作
|
||||
void SetAction(std::string actionName);
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
};
|
||||
|
||||
44
source_game/Asset/Character/Chr_Shadow.cpp
Normal file
44
source_game/Asset/Character/Chr_Shadow.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "Chr_Shadow.h"
|
||||
#include "Global/Global_Game.h"
|
||||
#include "Actor/Object/CharacterObject.h"
|
||||
#include "Asset/Character/Chr_Equipment.h"
|
||||
|
||||
void Chr_Shadow::Init(CharacterObject *parent)
|
||||
{
|
||||
// 调用RenderBase类的初始化 才能挂上标签
|
||||
RenderBase::Init();
|
||||
chr_parent = parent;
|
||||
SetRenderZOrder(1000000);
|
||||
SetPos(parent->GetPos());
|
||||
}
|
||||
|
||||
void Chr_Shadow::SetAction(std::string actionName)
|
||||
{
|
||||
// 先将原动作的Ani设置为不可见
|
||||
for (auto Ani : ActionAnis[CurrentActionTag])
|
||||
{
|
||||
Ani->Reset();
|
||||
Ani->SetVisible(false);
|
||||
}
|
||||
// 再将新动作的Ani设置为可见
|
||||
for (auto Ani : ActionAnis[actionName])
|
||||
{
|
||||
Ani->SetVisible(true);
|
||||
}
|
||||
CurrentActionTag = actionName;
|
||||
}
|
||||
|
||||
void Chr_Shadow::SetDirection(int dir)
|
||||
{
|
||||
VecFPos sc = GetScale();
|
||||
// 朝右
|
||||
if (dir == 0)
|
||||
{
|
||||
SetScale(VecFPos({SDL_fabsf(sc.x), sc.y}));
|
||||
}
|
||||
// 朝左
|
||||
else if (dir == 1)
|
||||
{
|
||||
SetScale(VecFPos({-SDL_fabsf(sc.x), sc.y}));
|
||||
}
|
||||
}
|
||||
29
source_game/Asset/Character/Chr_Shadow.h
Normal file
29
source_game/Asset/Character/Chr_Shadow.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
#include "EngineFrame/Component/Animation.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
class CharacterObject;
|
||||
class Chr_Shadow : public RenderBase
|
||||
{
|
||||
// 动作动画集合
|
||||
using ActionAniList = std::map<std::string, std::vector<RefPtr<Animation>>>;
|
||||
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
// 父对象
|
||||
CharacterObject *chr_parent;
|
||||
// 时装部位对应的动作动画集合
|
||||
ActionAniList ActionAnis;
|
||||
// 当前动作Tag
|
||||
std::string CurrentActionTag = "waiting";
|
||||
|
||||
// 初始化时
|
||||
void Init(CharacterObject *parent);
|
||||
// 设置动作
|
||||
void SetAction(std::string actionName);
|
||||
|
||||
// 设置方向
|
||||
void SetDirection(int dir);
|
||||
};
|
||||
39
source_game/Asset/Monster/Mon_Animation.cpp
Normal file
39
source_game/Asset/Monster/Mon_Animation.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "Mon_Animation.h"
|
||||
#include "Actor/Object/MonsterObject.h"
|
||||
#include "Global/Global_Game.h"
|
||||
void Mon_Animation::Init(MonsterObject *parent)
|
||||
{
|
||||
// 调用RenderBase类的初始化 才能挂上标签
|
||||
RenderBase::Init();
|
||||
parent->AddChild(this);
|
||||
mon_parent = parent;
|
||||
|
||||
GlobalMonsterScript::MonsterConfig Config = Global_Game::GetInstance().GetMonsterInfo(mon_parent->Id);
|
||||
|
||||
// 遍历所有动作Ani路径
|
||||
for (const auto &pair : Config.animationPath)
|
||||
{
|
||||
std::string ActionName = pair.first;
|
||||
std::string Path = std::string(Config.folder + Tool_toLowerCase(pair.second));
|
||||
|
||||
RefPtr<Animation> Ani = new Animation(Path);
|
||||
this->ActionAnis[ActionName] = Ani;
|
||||
Ani->SetVisible(false);
|
||||
this->AddChild(Ani);
|
||||
}
|
||||
|
||||
// 默认动作
|
||||
this->SetAction("waiting");
|
||||
}
|
||||
|
||||
void Mon_Animation::SetAction(std::string actionName)
|
||||
{
|
||||
// 先将原动作的Ani设置为不可见
|
||||
ActionAnis[CurrentActionTag]->Reset();
|
||||
ActionAnis[CurrentActionTag]->SetVisible(false);
|
||||
|
||||
// 再将新动作的Ani设置为可见
|
||||
ActionAnis[actionName]->SetVisible(true);
|
||||
|
||||
CurrentActionTag = actionName;
|
||||
}
|
||||
25
source_game/Asset/Monster/Mon_Animation.h
Normal file
25
source_game/Asset/Monster/Mon_Animation.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include "EngineFrame/Component/Animation.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
class MonsterObject;
|
||||
class Mon_Animation : public RenderBase
|
||||
{
|
||||
// 动作动画集合
|
||||
using ActionAniList = std::map<std::string, RefPtr<Animation>>;
|
||||
|
||||
private:
|
||||
// 父对象
|
||||
MonsterObject *mon_parent;
|
||||
// 动作动画集合
|
||||
ActionAniList ActionAnis;
|
||||
// 当前动作Tag
|
||||
std::string CurrentActionTag = "waiting";
|
||||
|
||||
public:
|
||||
// 初始化时 只完成基础的职业皮肤设置
|
||||
void Init(MonsterObject *parent);
|
||||
// 设置动作
|
||||
void SetAction(std::string actionName);
|
||||
};
|
||||
@@ -15,7 +15,7 @@ static SQInteger SQR_GetPosition(HSQUIRRELVM v)
|
||||
SQUserPointer ptr;
|
||||
sq_getuserpointer(v, 2, &ptr);
|
||||
BaseObject *obj = (BaseObject *)ptr;
|
||||
VecFPos3 Pos = obj->GetPosition();
|
||||
VecPos3 Pos = obj->GetPosition();
|
||||
|
||||
sq_newtable(v);
|
||||
sq_pushstring(v, _SC("x"), -1);
|
||||
@@ -40,7 +40,7 @@ static SQInteger SQR_SetPosition(HSQUIRRELVM v)
|
||||
sq_getfloat(v, 3, &PosX);
|
||||
sq_getfloat(v, 4, &PosY);
|
||||
sq_getfloat(v, 5, &PosZ);
|
||||
obj->SetPosition(VecFPos3(PosX, PosY, PosZ));
|
||||
obj->SetPosition(VecPos3(PosX, PosY, PosZ));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
336
source_game/Asset/Squirrel/Sqr_UI.hpp
Normal file
336
source_game/Asset/Squirrel/Sqr_UI.hpp
Normal file
@@ -0,0 +1,336 @@
|
||||
#pragma once
|
||||
#include "squirrel/SquirrelEx.h"
|
||||
#include "EngineFrame/Actor/Actor.h"
|
||||
#include "EngineFrame/Component/Sprite.h"
|
||||
|
||||
static SQInteger _file_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size))
|
||||
{
|
||||
Actor *Abli = (Actor *)p;
|
||||
Abli->Release();
|
||||
return 0;
|
||||
}
|
||||
static SQInteger SQR_RegisterDestruction(HSQUIRRELVM v)
|
||||
{
|
||||
// 析构函数测试
|
||||
SQUserPointer P;
|
||||
sq_getuserpointer(v, 2, &P);
|
||||
sq_setinstanceup(v, 3, P);
|
||||
sq_setreleasehook(v, 3, _file_releasehook);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SQInteger SQR_CreateActor(HSQUIRRELVM v)
|
||||
{
|
||||
RefPtr<Actor> act = new Actor();
|
||||
act->Retain();
|
||||
sq_pushuserpointer(v, act.Get());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static SQInteger SQR_AddChild(HSQUIRRELVM v)
|
||||
{
|
||||
SQUserPointer A_obj;
|
||||
sq_getuserpointer(v, 2, &A_obj);
|
||||
SQUserPointer B_obj;
|
||||
sq_getuserpointer(v, 3, &B_obj);
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
Actor *Bobj = (Actor *)B_obj;
|
||||
Aobj->AddChild(Bobj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SQInteger SQR_RemoveChild(HSQUIRRELVM v)
|
||||
{
|
||||
SQUserPointer A_obj;
|
||||
sq_getuserpointer(v, 2, &A_obj);
|
||||
SQUserPointer B_obj;
|
||||
sq_getuserpointer(v, 3, &B_obj);
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
Actor *Bobj = (Actor *)B_obj;
|
||||
Aobj->RemoveChild(Bobj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SQInteger SQR_GetZOrder(HSQUIRRELVM v)
|
||||
{
|
||||
SQUserPointer A_obj;
|
||||
sq_getuserpointer(v, 2, &A_obj);
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
sq_pushinteger(v, Aobj->GetRenderZOrder());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static SQInteger SQR_SetZOrder(HSQUIRRELVM v)
|
||||
{
|
||||
SQUserPointer A_obj;
|
||||
sq_getuserpointer(v, 2, &A_obj);
|
||||
SQInteger Value;
|
||||
sq_getinteger(v, 3, &Value);
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
Aobj->SetRenderZOrder(Value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SQInteger SQR_GetPos(HSQUIRRELVM v)
|
||||
{
|
||||
SQUserPointer A_obj;
|
||||
sq_getuserpointer(v, 2, &A_obj);
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
VecFPos Pos = Aobj->GetPos();
|
||||
|
||||
sq_newtable(v);
|
||||
sq_pushstring(v, _SC("x"), -1);
|
||||
sq_pushfloat(v, Pos.x);
|
||||
sq_newslot(v, 3, SQFalse);
|
||||
sq_pushstring(v, _SC("y"), -1);
|
||||
sq_pushfloat(v, Pos.y);
|
||||
sq_newslot(v, 3, SQFalse);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static SQInteger SQR_SetPos(HSQUIRRELVM v)
|
||||
{
|
||||
SQUserPointer A_obj;
|
||||
sq_getuserpointer(v, 2, &A_obj);
|
||||
|
||||
if (sq_gettop(v) == 3)
|
||||
{
|
||||
VecFPos Pos;
|
||||
sq_pushnull(v); // null iterator
|
||||
while (SQ_SUCCEEDED(sq_next(v, 3)))
|
||||
{
|
||||
SQFloat value;
|
||||
sq_getfloat(v, -1, &value);
|
||||
const SQChar *key;
|
||||
sq_getstring(v, -2, &key);
|
||||
|
||||
if (strcmp(key, _SC("x")) == 0)
|
||||
{
|
||||
Pos.x = value;
|
||||
}
|
||||
else if (strcmp(key, _SC("y")) == 0)
|
||||
{
|
||||
Pos.y = value;
|
||||
}
|
||||
sq_pop(v, 2);
|
||||
}
|
||||
sq_pop(v, 1);
|
||||
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
Aobj->SetPos(Pos);
|
||||
}
|
||||
else if (sq_gettop(v) == 4)
|
||||
{
|
||||
SQFloat X, Y;
|
||||
sq_getfloat(v, 3, &X);
|
||||
sq_getfloat(v, 4, &Y);
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
Aobj->SetPos(VecFPos(X, Y));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SQInteger SQR_GetAlpha(HSQUIRRELVM v)
|
||||
{
|
||||
SQUserPointer A_obj;
|
||||
sq_getuserpointer(v, 2, &A_obj);
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
|
||||
sq_pushfloat(v, Aobj->GetAlpha());
|
||||
return 1;
|
||||
}
|
||||
static SQInteger SQR_SetAlpha(HSQUIRRELVM v)
|
||||
{
|
||||
SQUserPointer A_obj;
|
||||
sq_getuserpointer(v, 2, &A_obj);
|
||||
SQFloat Value;
|
||||
sq_getfloat(v, 3, &Value);
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
Aobj->SetAlpha(Value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SQInteger SQR_GetScale(HSQUIRRELVM v)
|
||||
{
|
||||
SQUserPointer A_obj;
|
||||
sq_getuserpointer(v, 2, &A_obj);
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
VecFPos Pos = Aobj->GetScale();
|
||||
sq_newtable(v);
|
||||
sq_pushstring(v, _SC("x"), -1);
|
||||
sq_pushfloat(v, Pos.x);
|
||||
sq_newslot(v, 3, SQFalse);
|
||||
sq_pushstring(v, _SC("y"), -1);
|
||||
sq_pushfloat(v, Pos.y);
|
||||
sq_newslot(v, 3, SQFalse);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static SQInteger SQR_SetScale(HSQUIRRELVM v)
|
||||
{
|
||||
SQUserPointer A_obj;
|
||||
sq_getuserpointer(v, 2, &A_obj);
|
||||
|
||||
if (sq_gettop(v) == 3)
|
||||
{
|
||||
VecFPos Pos;
|
||||
sq_pushnull(v); // null iterator
|
||||
while (SQ_SUCCEEDED(sq_next(v, 3)))
|
||||
{
|
||||
SQFloat value;
|
||||
sq_getfloat(v, -1, &value);
|
||||
const SQChar *key;
|
||||
sq_getstring(v, -2, &key);
|
||||
|
||||
if (strcmp(key, _SC("x")) == 0)
|
||||
{
|
||||
Pos.x = value;
|
||||
}
|
||||
else if (strcmp(key, _SC("y")) == 0)
|
||||
{
|
||||
Pos.y = value;
|
||||
}
|
||||
sq_pop(v, 2);
|
||||
}
|
||||
sq_pop(v, 1);
|
||||
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
Aobj->SetScale(Pos);
|
||||
}
|
||||
else if (sq_gettop(v) == 4)
|
||||
{
|
||||
SQFloat X, Y;
|
||||
sq_getfloat(v, 3, &X);
|
||||
sq_getfloat(v, 4, &Y);
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
Aobj->SetScale(VecFPos(X, Y));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SQInteger SQR_GetRotation(HSQUIRRELVM v)
|
||||
{
|
||||
SQUserPointer A_obj;
|
||||
sq_getuserpointer(v, 2, &A_obj);
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
|
||||
sq_pushfloat(v, Aobj->GetRotation());
|
||||
}
|
||||
|
||||
static SQInteger SQR_SetRotation(HSQUIRRELVM v)
|
||||
{
|
||||
SQUserPointer A_obj;
|
||||
sq_getuserpointer(v, 2, &A_obj);
|
||||
SQFloat Value;
|
||||
sq_getfloat(v, 3, &Value);
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
Aobj->SetRotation(Value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SQInteger SQR_GetSize(HSQUIRRELVM v)
|
||||
{
|
||||
SQUserPointer A_obj;
|
||||
sq_getuserpointer(v, 2, &A_obj);
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
VecSize Pos = Aobj->GetSize();
|
||||
|
||||
sq_newtable(v);
|
||||
sq_pushstring(v, _SC("w"), -1);
|
||||
sq_pushfloat(v, Pos.width);
|
||||
sq_newslot(v, 3, SQFalse);
|
||||
sq_pushstring(v, _SC("h"), -1);
|
||||
sq_pushfloat(v, Pos.height);
|
||||
sq_newslot(v, 3, SQFalse);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static SQInteger SQR_SetSize(HSQUIRRELVM v)
|
||||
{
|
||||
SQUserPointer A_obj;
|
||||
sq_getuserpointer(v, 2, &A_obj);
|
||||
|
||||
if (sq_gettop(v) == 3)
|
||||
{
|
||||
VecSize Size;
|
||||
sq_pushnull(v); // null iterator
|
||||
while (SQ_SUCCEEDED(sq_next(v, 3)))
|
||||
{
|
||||
SQFloat value;
|
||||
sq_getfloat(v, -1, &value);
|
||||
const SQChar *key;
|
||||
sq_getstring(v, -2, &key);
|
||||
|
||||
if (strcmp(key, _SC("w")) == 0)
|
||||
{
|
||||
Size.width = value;
|
||||
}
|
||||
else if (strcmp(key, _SC("h")) == 0)
|
||||
{
|
||||
Size.height = value;
|
||||
}
|
||||
sq_pop(v, 2);
|
||||
}
|
||||
sq_pop(v, 1);
|
||||
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
Aobj->SetSize(Size);
|
||||
}
|
||||
else if (sq_gettop(v) == 4)
|
||||
{
|
||||
SQFloat X, Y;
|
||||
sq_getfloat(v, 3, &X);
|
||||
sq_getfloat(v, 4, &Y);
|
||||
Actor *Aobj = (Actor *)A_obj;
|
||||
Aobj->SetSize(VecSize(X, Y));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SQInteger SQR_CreateSprite(HSQUIRRELVM v)
|
||||
{
|
||||
const SQChar *ImgPath;
|
||||
SQInteger Idx;
|
||||
sq_getstring(v, 2, &ImgPath);
|
||||
sq_getinteger(v, 3, &Idx);
|
||||
RefPtr<Sprite> act = new Sprite(ImgPath, Idx);
|
||||
act->Retain();
|
||||
sq_pushuserpointer(v, act.Get());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void RegisterUINutApi(const SQChar *funcName, SQFUNCTION funcAddr, HSQUIRRELVM v)
|
||||
{
|
||||
sq_pushroottable(v);
|
||||
sq_pushstring(v, funcName, -1);
|
||||
sq_newclosure(v, funcAddr, 0);
|
||||
sq_newslot(v, -3, false);
|
||||
sq_poptop(v);
|
||||
}
|
||||
|
||||
static void RegisterUI()
|
||||
{
|
||||
SDL_Log("初始化 UI函数-松鼠脚本!");
|
||||
HSQUIRRELVM v = SquirrelEx::GetInstance().GetSquirrelVM();
|
||||
|
||||
// 析构函数
|
||||
RegisterUINutApi(_SC("sq_RegisterDestruction"), SQR_RegisterDestruction, v);
|
||||
|
||||
RegisterUINutApi(_SC("sq_CreateActor"), SQR_CreateActor, v);
|
||||
RegisterUINutApi(_SC("sq_AddChild"), SQR_AddChild, v);
|
||||
RegisterUINutApi(_SC("sq_RemoveChild"), SQR_RemoveChild, v);
|
||||
RegisterUINutApi(_SC("sq_GetZOrder"), SQR_GetZOrder, v);
|
||||
RegisterUINutApi(_SC("sq_SetZOrder"), SQR_SetZOrder, v);
|
||||
RegisterUINutApi(_SC("sq_GetPos"), SQR_GetPos, v);
|
||||
RegisterUINutApi(_SC("sq_SetPos"), SQR_SetPos, v);
|
||||
RegisterUINutApi(_SC("sq_GetAlpha"), SQR_GetAlpha, v);
|
||||
RegisterUINutApi(_SC("sq_SetAlpha"), SQR_SetAlpha, v);
|
||||
RegisterUINutApi(_SC("sq_GetScale"), SQR_GetScale, v);
|
||||
RegisterUINutApi(_SC("sq_SetScale"), SQR_SetScale, v);
|
||||
RegisterUINutApi(_SC("sq_GetRotation"), SQR_GetRotation, v);
|
||||
RegisterUINutApi(_SC("sq_SetRotation"), SQR_SetRotation, v);
|
||||
RegisterUINutApi(_SC("sq_GetSize"), SQR_GetSize, v);
|
||||
RegisterUINutApi(_SC("sq_SetSize"), SQR_SetSize, v);
|
||||
|
||||
RegisterUINutApi(_SC("sq_CreateSprite"), SQR_CreateSprite, v);
|
||||
}
|
||||
@@ -3,6 +3,8 @@
|
||||
void SquirrelManager::Init()
|
||||
{
|
||||
SDL_Log("开始初始化sqr管理器!");
|
||||
// UI函数
|
||||
RegisterUI();
|
||||
// 基础对象
|
||||
RegisterBaseObject();
|
||||
// 动态对象
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "Asset/Squirrel/Sqr_UI.hpp"
|
||||
#include "Asset/Squirrel/Sqr_BaseObject.hpp"
|
||||
#include "Asset/Squirrel/Sqr_ActiveObject.hpp"
|
||||
#include "Asset/Squirrel/Sqr_CharacterObject.hpp"
|
||||
|
||||
Reference in New Issue
Block a user