2DProject 및 Sprite 생성

1. 2DProject 생성
2. Sprite 및 AnimationController
This commit is contained in:
Mingu Kim
2025-01-25 00:43:18 +09:00
commit 20c7e2ba3a
1179 changed files with 172652 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7ebc2b0f78db3494abe728ffd6a20312
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
using UnityEngine;
/// <summary>
/// This class will apply continuous damage to the Player as long as it stay inside the trigger on the same object
/// </summary>
public class DamageZone : MonoBehaviour
{
void OnTriggerStay2D(Collider2D other)
{
RubyController controller = other.GetComponent<RubyController>();
if (controller != null)
{
//the controller will take care of ignoring the damage during the invincibility time.
controller.ChangeHealth(-1);
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: f4e6a07322502ea4fb252fe89272842a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 271239
packageName: 'Unity Learn | 2D Beginner: Adventure Game Complete Project | URP'
packageVersion: 1.1
assetPath: Assets/UnityTechnologies/Final/Scripts/Final/DamageZone.cs
uploadId: 701356

View File

@@ -0,0 +1,93 @@
using System;
using UnityEngine;
/// <summary>
/// This class handle Enemy behaviour. It make them walk back & forth as long as they aren't fixed, and then just idle
/// without being able to interact with the player anymore once fixed.
/// </summary>
public class Enemy : MonoBehaviour
{
// ====== ENEMY MOVEMENT ========
public float speed;
public float timeToChange;
public bool horizontal;
public GameObject smokeParticleEffect;
public ParticleSystem fixedParticleEffect;
public AudioClip hitSound;
public AudioClip fixedSound;
Rigidbody2D rigidbody2d;
float remainingTimeToChange;
Vector2 direction = Vector2.right;
bool repaired = false;
// ===== ANIMATION ========
Animator animator;
// ================= SOUNDS =======================
AudioSource audioSource;
void Start ()
{
rigidbody2d = GetComponent<Rigidbody2D>();
remainingTimeToChange = timeToChange;
direction = horizontal ? Vector2.right : Vector2.down;
animator = GetComponent<Animator>();
audioSource = GetComponent<AudioSource>();
}
void Update()
{
if(repaired)
return;
remainingTimeToChange -= Time.deltaTime;
if (remainingTimeToChange <= 0)
{
remainingTimeToChange += timeToChange;
direction *= -1;
}
animator.SetFloat("ForwardX", direction.x);
animator.SetFloat("ForwardY", direction.y);
}
void FixedUpdate()
{
rigidbody2d.MovePosition(rigidbody2d.position + direction * speed * Time.deltaTime);
}
void OnCollisionStay2D(Collision2D other)
{
if(repaired)
return;
RubyController controller = other.collider.GetComponent<RubyController>();
if(controller != null)
controller.ChangeHealth(-1);
}
public void Fix()
{
animator.SetTrigger("Fixed");
repaired = true;
smokeParticleEffect.SetActive(false);
Instantiate(fixedParticleEffect, transform.position + Vector3.up * 0.5f, Quaternion.identity);
//we don't want that enemy to react to the player or bullet anymore, remove its reigidbody from the simulation
rigidbody2d.simulated = false;
audioSource.Stop();
audioSource.PlayOneShot(hitSound);
audioSource.PlayOneShot(fixedSound);
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: c355cf67d54abee4aae3b97fd7e93987
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 271239
packageName: 'Unity Learn | 2D Beginner: Adventure Game Complete Project | URP'
packageVersion: 1.1
assetPath: Assets/UnityTechnologies/Final/Scripts/Final/Enemy.cs
uploadId: 701356

View File

@@ -0,0 +1,18 @@
using UnityEngine;
/// <summary>
/// Will handle giving health to the character when they enter the trigger.
/// </summary>
public class HealthCollectible : MonoBehaviour
{
void OnTriggerEnter2D(Collider2D other)
{
RubyController controller = other.GetComponent<RubyController>();
if (controller != null)
{
controller.ChangeHealth(1);
Destroy(gameObject);
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: c970e88e32a497f4ca33410e94cdcc3e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 271239
packageName: 'Unity Learn | 2D Beginner: Adventure Game Complete Project | URP'
packageVersion: 1.1
assetPath: Assets/UnityTechnologies/Final/Scripts/Final/HealthCollectible.cs
uploadId: 701356

View File

@@ -0,0 +1,10 @@
using UnityEngine;
/// <summary>
/// This class define a NonPlayerCharacter. It is only used to "mark" a GameObject as NPC, the raycast for dialog in
/// the player controller will check if the object hit have that script to define if it can be talked to.
/// </summary>
public class NonPlayerCharacter : MonoBehaviour
{
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 5d950830031d2b949ab94e02d15d34c8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 271239
packageName: 'Unity Learn | 2D Beginner: Adventure Game Complete Project | URP'
packageVersion: 1.1
assetPath: Assets/UnityTechnologies/Final/Scripts/Final/NonPlayerCharacter.cs
uploadId: 701356

View File

@@ -0,0 +1,40 @@
using UnityEngine;
/// <summary>
/// Handle the projectile launched by the player to fix the robots.
/// </summary>
public class Projectile : MonoBehaviour
{
Rigidbody2D rigidbody2d;
void Awake()
{
rigidbody2d = GetComponent<Rigidbody2D>();
}
void Update()
{
//destroy the projectile when it reach a distance of 1000.0f from the origin
if(transform.position.magnitude > 1000.0f)
Destroy(gameObject);
}
//called by the player controller after it instantiate a new projectile to launch it.
public void Launch(Vector2 direction, float force)
{
rigidbody2d.AddForce(direction * force);
}
void OnCollisionEnter2D(Collision2D other)
{
Enemy e = other.collider.GetComponent<Enemy>();
//if the object we touched wasn't an enemy, just destroy the projectile.
if (e != null)
{
e.Fix();
}
Destroy(gameObject);
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: a3798fb0019c74c44a1c33a26d74054e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 271239
packageName: 'Unity Learn | 2D Beginner: Adventure Game Complete Project | URP'
packageVersion: 1.1
assetPath: Assets/UnityTechnologies/Final/Scripts/Final/Projectile.cs
uploadId: 701356

View File

@@ -0,0 +1,177 @@
using System;
using UnityEngine;
using UnityEngine.InputSystem;
public class RubyController : MonoBehaviour
{
// ========= MOVEMENT =================
public float speed = 4;
public InputAction moveAction;
// ======== HEALTH ==========
public int maxHealth = 5;
public float timeInvincible = 2.0f;
public Transform respawnPosition;
public ParticleSystem hitParticle;
// ======== PROJECTILE ==========
public GameObject projectilePrefab;
public InputAction launchAction;
// ======== AUDIO ==========
public AudioClip hitSound;
public AudioClip shootingSound;
// ======== HEALTH ==========
public int health
{
get { return currentHealth; }
}
// ======== DIALOGUE ==========
public InputAction dialogAction;
// =========== MOVEMENT ==============
Rigidbody2D rigidbody2d;
Vector2 currentInput;
// ======== HEALTH ==========
int currentHealth;
float invincibleTimer;
bool isInvincible;
// ==== ANIMATION =====
Animator animator;
Vector2 lookDirection = new Vector2(1, 0);
// ================= SOUNDS =======================
AudioSource audioSource;
void Start()
{
// =========== MOVEMENT ==============
rigidbody2d = GetComponent<Rigidbody2D>();
moveAction.Enable();
// ======== HEALTH ==========
invincibleTimer = -1.0f;
currentHealth = maxHealth;
// ==== ANIMATION =====
animator = GetComponent<Animator>();
// ==== AUDIO =====
audioSource = GetComponent<AudioSource>();
// ==== ACTIONS ====
launchAction.Enable();
dialogAction.Enable();
launchAction.performed += LaunchProjectile;
}
void Update()
{
// ================= HEALTH ====================
if (isInvincible)
{
invincibleTimer -= Time.deltaTime;
if (invincibleTimer < 0)
isInvincible = false;
}
// ============== MOVEMENT ======================
Vector2 move = moveAction.ReadValue<Vector2>();
if(!Mathf.Approximately(move.x, 0.0f) || !Mathf.Approximately(move.y, 0.0f))
{
lookDirection.Set(move.x, move.y);
lookDirection.Normalize();
}
currentInput = move;
// ============== ANIMATION =======================
animator.SetFloat("Look X", lookDirection.x);
animator.SetFloat("Look Y", lookDirection.y);
animator.SetFloat("Speed", move.magnitude);
// ======== DIALOGUE ==========
if (dialogAction.WasPressedThisFrame())
{
RaycastHit2D hit = Physics2D.Raycast(rigidbody2d.position + Vector2.up * 0.2f, lookDirection, 1.5f, 1 << LayerMask.NameToLayer("NPC"));
if (hit.collider != null)
{
NonPlayerCharacter character = hit.collider.GetComponent<NonPlayerCharacter>();
if (character != null)
{
UIHandler.instance.DisplayDialog();
}
}
}
}
void FixedUpdate()
{
Vector2 position = rigidbody2d.position;
position = position + currentInput * speed * Time.deltaTime;
rigidbody2d.MovePosition(position);
}
// ===================== HEALTH ==================
public void ChangeHealth(int amount)
{
if (amount < 0)
{
if (isInvincible)
return;
isInvincible = true;
invincibleTimer = timeInvincible;
animator.SetTrigger("Hit");
audioSource.PlayOneShot(hitSound);
Instantiate(hitParticle, transform.position + Vector3.up * 0.5f, Quaternion.identity);
}
currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
if(currentHealth == 0)
Respawn();
UIHandler.instance.SetHealthValue(currentHealth / (float)maxHealth);
//UIHealthBar.Instance.SetValue(currentHealth / (float)maxHealth);
}
void Respawn()
{
ChangeHealth(maxHealth);
transform.position = respawnPosition.position;
}
// =============== PROJECTICLE ========================
void LaunchProjectile(InputAction.CallbackContext context)
{
GameObject projectileObject = Instantiate(projectilePrefab, rigidbody2d.position + Vector2.up * 0.5f, Quaternion.identity);
Projectile projectile = projectileObject.GetComponent<Projectile>();
projectile.Launch(lookDirection, 300);
animator.SetTrigger("Launch");
audioSource.PlayOneShot(shootingSound);
}
// =============== SOUND ==========================
//Allow to play a sound on the player sound source. used by Collectible
public void PlaySound(AudioClip clip)
{
audioSource.PlayOneShot(clip);
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 7be5c9220d0d0504591c18793dd6ad18
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 271239
packageName: 'Unity Learn | 2D Beginner: Adventure Game Complete Project | URP'
packageVersion: 1.1
assetPath: Assets/UnityTechnologies/Final/Scripts/Final/RubyController.cs
uploadId: 701356

View File

@@ -0,0 +1,56 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
public class UIHandler : MonoBehaviour
{
public static UIHandler instance { get; private set; }
public float displayTime = 4.0f;
private VisualElement m_Healthbar;
private VisualElement m_DialogWindow;
private float m_TimerDisplay;
private void Awake()
{
instance = this;
}
void Start()
{
UIDocument uiDocument = GetComponent<UIDocument>();
m_Healthbar = uiDocument.rootVisualElement.Q<VisualElement>("Healthbar");
m_DialogWindow = uiDocument.rootVisualElement.Q<VisualElement>("DialogWindow");
m_DialogWindow.style.display = DisplayStyle.None;
m_TimerDisplay = -1.0f;
SetHealthValue(1.0f);
}
private void Update()
{
if (m_TimerDisplay > 0)
{
m_TimerDisplay -= Time.deltaTime;
if (m_TimerDisplay < 0)
{
m_DialogWindow.style.display = DisplayStyle.None;
}
}
}
public void DisplayDialog()
{
m_DialogWindow.style.display = DisplayStyle.Flex;
m_TimerDisplay = displayTime;
}
public void SetHealthValue(float percentage)
{
m_Healthbar.style.width = Length.Percent(100 * percentage);
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: a1c9df2c56bf84f45bc0c0cd1ba881fd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 271239
packageName: 'Unity Learn | 2D Beginner: Adventure Game Complete Project | URP'
packageVersion: 1.1
assetPath: Assets/UnityTechnologies/Final/Scripts/Final/UIHandler.cs
uploadId: 701356