//라이프 사이클
Awake()// 게임오브젝트가 처음생성될때 실행 , 초기화 영역
-> OnEnable()// 게임오브젝트 또는 스크립트가 활성화 될때
-> Start()// 업데이트전 실행 , 초기화 영역
/* 프레임
-> FixedUpdate()// 고정된 실행주기(cpu 많이사용, 고로 물리적인 규칙)
-> Update()// 게임 로직업데이트(주기적으로 변하는 , 컴퓨터의 사향에 따라 프레임이 바뀜)
-> LateUpdate()// 모든업데이트가 끝난후(카메라나 로직의후처리)
*/
/*해체
-> OnDisable()// 게임오브젝트 또는 스크립트가 비활성화 될때
-> OnDestroy()// 게임오브젝트가 삭제될 때
//Input 클래스
게임의 입력을 관리하는 클래스
anyKeyDown//아무입력을 최초로 받을때 true
anyKey//아무입력을 받을때 true
-> 상황 down / stay / up
GetKey [Down(KeyCode)/(KeyCode)/Up(KeyCode)]
KeyCode 참고 https://docs.unity3d.com/kr/530/ScriptReference/KeyCode.html
GetMouseButton [Down(0 or 1)/(0 or 1)/Up(0 or 1)] // 0 : 마우스외쪽 1 : 마우스오른쪽
projeectSetting -> input //inputManager 버튼을 만들수있음
GetButton [Down(ex)"Jump")/(ex)"Jump")/Up(ex)"Jump")]
GetAxis("Horizontal"or"Vertical") // 수평,수직버튼 입력을 받으면 float값 -1~1까지 가중치를 사용할때 반환
GetAxisRaw("Horizontal"or"Vertical") // 수평,수직버튼 입력을 받으면 int값 -1과1을 반환
//Transform 클래스
오브젝트는 변수 transform을 항상 가지고 있음.
Translate()//백터 값을 현재 위치에 더하는 함수
*백터값 방향과 그에 대한 크기값
응용
Vector3 vec=new Vector3(GetAxis("Horizontal"),GetAxis(Vertical"),0);
//Vector3 vec=new Vector3(GetAxisRaw("Horizontal"),GetAxisRaw(Vertical"),0);
transform.Translate(vec);
transform.Rotate(Vector3.up*rotateSpeed,Space.world )
Space(Self or World)
positon변수 : 좌표적 값
//Vector클래스
Vector3 vec=new Vector3(0,0,0);//3차원
Vector2 vec=new Vector2(0,0);//2차원
기본으로 제공하는 정적값(static)
Vector3 vec;
vec = Vector3 .right; // new Vector3(1, 0, 0);
vec = Vector3 .left; // new Vector3(-1, 0, 0);
vec = Vector3 .up; // new Vector3(0, 1, 0);
vec = Vector3 .down; // new Vector3(0, -1, 0);
vec = Vector3 .forward; // new Vector3(0, 0, 1);
vec = Vector3 .back; // new Vector3(0, 0, -1);
vec = Vector3 .zero; // new Vector3(0, 0, 0);
vec = Vector3 .one; // new Vector3(1, 1, 1);
연산 가능,추출 가능(ex)vec.x)
MoveTowards(현재위치,목표위치,속도)// 등속이동
응용
transform.position=Vector3.MoveTowards(transform.position,target,2f);
SmoothDamp(현재위치,목표위치,참조 속도,속도)// 부드러운 감속운동
응용
Vector3 velo=Vector3.zero;
transform.position=Vector3.SmoothDamp(transform.position,target,ref velo,0.5f);//속도에 반비례한 빠르기
*ref : 참조 접근 -> 실시간으로 바뀌는 값 적용가능
Lerf(현재위치,목표위치,속도)//선형보간,SmoothDamp보다 감속시간이 김
응용
transform.position=Vector3.Lerf(transform.position,target,0.1f);//속도는1이 max
Slerf(현재위치,목표위치,속도)//구면선형보간,호를 그리면서 이동(포물선 이동)
응용
transform.position=Vector3.Slerf(transform.position,target,0.1f);//속도는1이 max
//Time 클래스
deltaTime 값은 프레임이 적으면 크고, 프레임이 많으면 작음
//RigidBody 변수
Rigidbody rigid;//선언
rigid=GetComponent<Rigidbody>();//초기화
rigid.velocity=Vector3.right;//현재속도
rigid.AddForce(Vec,ForceMode.Inpulse);//Vec의 방향과 크기로 힘을줌,무게값에따라 힘을 더욱 줘야함
ForceMode// 힘을 주는 방식(가속,무게 반영) https://docs.unity3d.com/kr/530/ScriptReference/ForceMode.html
rigid.AddTorque(Vec,ForceMode.Inpulse);//Vec의 방향을 축으로 회전력이 생김
rigid.velocity.normalized // 백터크기를 1로 만든상태
사용예 ) rigid.velocity=new Vector2(rigid.velocity.normalized.x*0.5f,rigid.velocity.y);// 키를 땟을 경우 속도를 줄여주는 소스
//MeshRenderer변수,Material 변수
MeshRenderer mesh;오브젝트의 재질 접근
Material mat;
//Collision(Enter/Stay/Exit) 물리적 충돌이 (시작할때/머무를때/끝낫을때) 호출되는 함수
private void OnCollisionEnter(Collision collision){
if(collision.gameObject.name=="My Ball"){
mat.color=new Color(0,0,0)//색 변경 0~1
}
}
//Tirigger이벤트 collider의trigger를 체크해야함
//Tirigger(Enter/Stay/Exit) 충돌체 충돌이 (시작할때/머무를때/끝낫을때) 호출되는 함수
private void OnTiriggerStay(Collider other){
if(other.name=="My Ball"){
mat.color=new Color(0,0,0)//색 변경 0~1
}
}
// 프레임 고정
Application.targetFrameRate = 60;// Awake문에넣어 프레임을 고정한다.ios(애플)의 경우 기본 프레임이 30 으로 고정이되어 있기 때문에 느리게 보일수 있기에 프레임 고정을 하면 좋다
위 함수를 사용할때는 VSync(View SyncTime)를 조절 해야 한다. 조절하기 위해서는 Edit -> Project Setting -> Quality의 인스펙터안에서 Other의 Vsync Count를 Don't Sync로 교채하면된다.
// 리스트의 사용
배열과 다르게 중간의 내용을 삭제할수있다.
ex) List <string> item =new List<string>();
for(int i =0;i<4;i+){
item.Add(i+"번 내용");
}
리스트 관련 함수: https://www.csharp-examples.net/list/
// 스트링을 통한 스위치문
//foreach문
foreach(string item in items){
Debug.Log(item);
}
for(int i=0;i<items.Length;i++){
Debug.Log(items[i]);
}
//인스턴스화(구조체와 비슷하게 사용
Player p1 =new Player;//Player라는 소스가 있어야하며 public으로 지정해야함
p1.id="1q2w3e";
//클래스 생성자
Player man1 =new Player("ksh",21);
//Player의 소스안
public class Plater(){
....
public Player(string pname,int page){
name=pname;
age=page;
}
}
//부모자식화
public class Player: Actor // Actor : 부모 Player : 자식
//Ray
*DrawRay() : 에디터 상에서 만 Ray(선)를 그려주는 함수
Debug.DrawRay(rigid.poistion,vector3.down,new Color(0,1,0));
*RayCastHit : Ray에 닿은 오브젝트(관통 x)
//------------ 점프 애니메이션 취소 소스
if(rigid.velocity.y<0){
RayCstHit2D rayHit=Phsics2D.RayCast(rigid.poistion,vector3.down,1,LayerMask.GetMask("Platform"));
/* rigid.poistion의 아래로 1만큼내리고 닿은오브잭트의 레이어가 플렛폼인경우 */
if(rayHit.collider != null){
if(rayHit.distance < 0.5f){anim.SetBool("isJumping",false);}
//Debug.Log(rayHit.collider.name);
}}
//-------------- 앞의 땅점검 소스
rigid.velocity =new Vector2(nextMove,rigid.velocity.y)
Vector frontVec = new Vector2(rigid.position.x+ nextMove,rigid.position.y);
DeBug.DrawRay(frintVec,Vector3.down,new Color(0,1,0));
RayCstHit2D rayHit=Phsics2D.RayCast(rigid.poistion,vector3.down,1,LayerMask.GetMask("Platform"));
if(rayHit.collider == null){// 아무것도 없을 경우
nextMove*=-1;
CancelInvoke();
Invoke("Think",2);
}
//Random 랜덤 수를 생성하는 로직 관련 클래스
Range() : 최소 ~ 최대 범위의 랜덤 수 생성
* 최소<= Range(최소,최대) < 최대
// Invoke(함수이름,시간) 주어진 시간이 지난뒤, 지정된 함수를 실행하는 함수// 딜레이
//CancelInvoke(); 딜레이 취소
/// 소스들
*최대 가속도설정 * // AddForce를 썻을 경우 필요--------------------------------------------------------------------------
*스프라이트 랜더러를 통한 x축 회전 *--------------------------------------------------------------------------
*점프*--------------------------------------------------------------------------
*animation*--------------------------------------------------------------------------
재귀함수--------------------------------------------------------------------------
충돌관련--------------------------------------------------------------------------
void OnCollisionEnter2D(Collision2D collision) {
if(collision.gameObject.tag == "Enemy"){
if(rigid.velocity.y<0&&transfirm.position.y){
OnAttack(collision.transform)
gameManager.stagePoint+=100;
}//Attack
else{
OnDamaged(collision.transform.position);
gameManager.Health-=1;
}//Damaged
}
void OnTriggerEnter2D(Collider2D collision) {// Kinematic설정필수
if(collision.gameObject.tag == "Item"){//itemAdd
collision.gameObject.SetActive(false);
bool isBronze = collision.gameObjcet.name.Contains("Bronze");
bool isSilver = collision.gameObjcet.name.Contains("Silver");
bool isGold = collision.gameObjcet.name.Contains("Gold");
if(isBronze){gameManager.stagePoint+=100;}
else if(isSilver){gameManager.stagePoint+=200;}
else if(isGold){gameManager.stagePoint+=300;}
}
else if(collision.gameObject.tag == "Goal"){//into the Goal
gameManager.NextStage();
}
}
void OnAttack(Transform enemy){
//Point
//Reaction Force
rigid.AddForce(Vector2.up*5 ,ForceMode2D.Impulse);
//Enemy Die
EnemyMove enemyMove =enemy.GetComponet<EnemyMove>();
enemyMove.OnDamaged();
}
void OnDamaged(Vector2 targetPos){
// Change Layer (Immortal Active)
gameObject.layer = 11;
// View Alpha
spriteRenderer.color = new Color(1, 1, 1, 0.4f);
// Reaction Force
int dirc = transform.position.x - targetPos.x > 0 ? 1 : -1;
rigid.AddForce(new Vector2(dirc, 1)*7 ,ForceMode2D.Impulse);
Invoke("OffDamaged", 3);
}
void OffDamaged(){
gameObject.layer = 10;
spriteRenderer.color = new Color(1, 1, 1, 1);
}
//Class EnemyMove.cs
public void OnDamaged(){
//Sprite Alpha
spriteRenderer.color = new Color(1, 1, 1, 0.4f);
//Sprite Flip Y
spriteRenderer.flipY=truel
//Collider Disable
capsuleCollider.enabled=false;
//Die Effect Jump
rigid.AddForce(Vector2.up*5 ,ForceMode2D.Impulse);
//Destroy
Invoke("DeActive", 5);
}
void DeActive(){
gameObject.SetActive(false);
}
//GameManager.cs
public void NextStage(){
stageIndex++;
totalPoint+=stagePoint;
stagePoint=0;
sceneManager.LoadScene("stage"+stageIndex.toString());
}
낙하시------------------------------------------------------------------
Scene이동이 아닌 부모자식을 통한게임 오브젝트 온오프로 스테이지 옴기기 --------------------------------
public GameObject[] Stages;
public void NextStage(){
if(stageIndex<Stages.Length-1){
Stages[stageIndex].SetActive(false);
stageIndex++;
Stages[stageIndex].SetActive(true);
PlayerReposition();}
else{
Debug.Log("Clear")
}
}
AudioSource 통합관리--------------------------------
Top 뷰 움직임 및 애니메이션----------------------------------------------
float h,v ;
Vector3 dirSpeed;
GameObjcet scanObjct;
void Update(){
h=Input.GetAxisRaw("Horizontal");
v=Input.GetAxisRaw("Vertical");
bool hDown =Input.GetButtonDown("Horizontal");
bool hUp =Input.GetButtonUp("Horizontal");
bool vDown =Input.GetButtonDown("Vertical");
bool vUp =Input.GetButtonUp("Vertical");
//CheckHorizontalMove
if(hDown)
isHorizontalMove =true;
else if(hDown)
isHorizontalMove =false;
else if(hUp || vUp)
isHorizontalMove = h!=0;
//Animation
if(anim.GetIntger("hAxixRaw")!=h){
anim.SetBool("isChange",true);
anim.SetInt("hAxixRaw",(int)h);
}
else if(anim.GetIntger("vAxixRaw")!=v){
anim.SetBool("isChange",true);
anim.SetInt("vAxixRaw",(int)v);
}
else{
anim.SetBool("isChange",false);
}
//Dircetion
if(vDown&&v==1)
dirVec=Vector3.up;
else if(vDown&&v==-1)
dirVec=Vector3.down;
else if(hDown&&h==-1)
dirVec=Vector3.left;
else if(hDown&&h==1)
dirVec=Vector3.right;
//ScanObject
if(Input.GetButtonDown("Jump")&&scanObject!=null){
gameManager.Action(scanObject);
}
}
void FixedUpdate(){
//Move
Vector2 moveVec =isHorizonMove?new Vector2(h,0):new Vector2(0,v);
rigid.velocity=moveVec*Speed;
//Ray(Scan)
//Debug.DrawRay(rigid.position,dirVec*0.7f,new Color(0,1,0));
RaycastHit2d rayHit=Physics2D.RayCast(rigid.position,dirVec*0.7f,LayerMask.GetMask("Object"));
if(rayHit.collider != null){
scanObjct=rayHit.collider.gameObject;
}
else
scanObject=null;
}
대화시스템&&퀘스트 시스템---------------------------------------------
// ObjData .cs
public class ObjData : MonBehaviour{
public int id;//각각의 고유한 ID ex) 035ac58 ,002
public bool isNpc;
}
// TalkManager.cs
public class TalkManager : MonBehaviour{
Dictionary<int,string[]> talkData;//대화 데이터 저장
Dictionary<int,Sprite> portraitData;//대화 데이터 저장
/*
*/
public Sprite[] portraitArr;
void Awake(){
talkData=newDictionary<int,string[]>();
portraitData=newDictionary<int,Sprite>();
GenrateData();
}
void GenerateData(){
//talkData
//npc A:1000 B:2000
//object: 100
talkData.Add(1000,new string[] {"1번대화문:0","2번대화문:1"});//NPC
talkData.Add(100,new string[] {"1번대화문","2번대화문"});
//questData
//npc A:1000 B:2000
//int 형식 => NpcID + QuestNum
talkData.Add(1000+10,new string[] {"1.1번대화문:0","1.2번대화문:1","1.3번대화문:0","1.4번대화문:1"});//NPC
talkData.Add(2000+11,new string[] {"2.1번대화문:4","2.2번대화문:5","2.3번대화문:4","2.4번대화문:5"});//NPC
//portraitData
//0: 1.Normal , 1: 1.Speak , 2: 1.Happy , 1.3: Angry , 4: 2.Normal , 5: 2.Speak , 6: 2.Happy , 7: 2.Angry
// int 형식 => NpcID + 첨자
portraitData.Add(1000+0,portraitArr[0]);
portraitData.Add(1000+1,portraitArr[1]);
portraitData.Add(1000+2,portraitArr[2]);
portraitData.Add(1000+3,portraitArr[3]);
portraitData.Add(1000+4,portraitArr[4]);
portraitData.Add(1000+5,portraitArr[5]);
portraitData.Add(1000+6,portraitArr[6]);
portraitData.Add(1000+7,portraitArr[7]);
}
public string GetTalk(int id,int talkIndex){
if(!talkData.ContainsKey(id)){
if(!talkData.ContainsKey(id-id%10)){
return GetTalk(id-id%100,talkIndex);
else{
return GetTalk(id-id%10,talkIndex);
}
}
if(talkIndex==talkData[id].Length){
return null;
}
else{
return talkData[id][talkIndex];
}
}
public Sprite GetPortrait(int id,int portraitIndex){
return talkData[id+portraitIndex];
}
void Update(){
}
}
// QuestData .cs//유니티 엔진 필요없음
public class QuestData {
public string questName;
public int[] npcID;
public QuestData(string name,int[] npc){
questName=name;
npcID=npc;
}
}
// QuestManager.cs
public class QuestManager : MonBehaviour{
public int questId;//현재 진행중인 퀘스트 번호,임으로 10부터시작
public int questActionIndex;//초기값 0
Dictionary<int,QuestData> questList;//대화 데이터 저장
void Awake(){
questList=new Dictionary<int,QuestData>();
GenerateData();
}
void GenerateData(){
questList.Add(10,new QuestData("순서대로대화하기",new int[] {1000,2000}));
}
public int GetQuestTalkIndex(int id){
return questId+questActionIndex;
}
public string CheckQuest(int id){
if(id ==questList[questId].npcId[questActionIndex])questActionIndex++;
if(questActionIndex ==questList[questId].npcId.length)Nextquest();
return questList[questId].questName;
}
void Nextquest(){
questID +=10;
questActionIndex=0;
}
}
// GameManager.cs
public class TalkManager : MonBehaviour{
public TalkManager talkManager;
public QuestManager questManager;
public GameObject talkPanel;
public Text talkText;
public Image portraitImg;
public GameObjcet scanObject;
public bool isAction;
public int talkIndex;
public void Action(GameObject scanObj){
if(scanObjcet!=scanObj){
scanObjcet=scanObj;
talkIndex=0;
}
ObjData objData=scanObject.GetComponet<ObjData>();
Talk(objData.id,objData.isNpc);
talkPanel.SetActive(isAction);
}
void Talk(int id,bool isNpc){
//SetTalkData
int questTalkIndex= questManager.GetQuestTalkIndex(id);
string talkData=talkManager.GetTalk(id+questTalkIndex,talkIndex);
//end Talk
if(talkData==null){
isAction=false;
talkIndex=0;
questManager.CheckQuest;
return;
}
//ContinueTalk
if(isNpc){
talkText.text=talkData.Split(':')[0];
portraitImg.color=new Color(1,1,1,1);
portraitImg.sprite=talkManager.GetPortrait(id,int.Parse(talkData.Split(':')[1]));
}
else{
talkText.text=talkData;
portraitImg.color=new Color(1,1,1,0);
}
isAction =true;
talkIndex++;
}
}
-----------------------------------------------------------------------------------------
'잡다한지식 > 게임개발' 카테고리의 다른 글
유니티 2019-11-27 공부 (0) | 2019.11.27 |
---|---|
유니티2D 관련지식 (0) | 2019.11.19 |
소스들저장용(C#-unity)3D 공게임 (0) | 2019.11.17 |
유니티 UI관련 지식 (0) | 2019.11.17 |
유니티 컴퍼넌트관련 지식 (0) | 2019.11.16 |