// GameBootstrap.cs // Cole este arquivo em Assets/ e o Unity fará o resto automaticamente. // // Recursos criados automaticamente (após a primeira compilação): // - Player "DogPlayer" com movimento WASD + Espaço pular // - Canvas + HUD (contador de ossos) no canto superior direito // - Bone.prefab (capsule com Rigidbody) e alguns ossos espalhados // - Animator Controller básico em Assets/DogAnimator.controller // - Camera principal configurada para seguir o player // - Cena com uma pequena cidade procedural (prédios em grade) // - Arquivo marcador Assets/DogGame_SetupDone.txt para evitar reruns using UnityEngine; using System.Collections; #if UNITY_EDITOR using UnityEditor; using UnityEditor.Animations; using System.IO; #endif public class GameBootstrap : MonoBehaviour { // ---------- RUNTIME: DogController ---------- public class DogController : MonoBehaviour { [Header("Movement")] public float moveSpeed = 6f; public float jumpForce = 6f; public float groundCheckDistance = 0.6f; public LayerMask groundMask; private Rigidbody rb; private int bonesCollected = 0; private UnityEngine.UI.Text bonesText; void Awake() { rb = GetComponent(); if (rb == null) rb = gameObject.AddComponent(); // ensure collider exists if (GetComponent() == null) { var col = gameObject.AddComponent(); col.material = new PhysicMaterial() { frictionCombine = PhysicMaterialCombine.Multiply }; } // Find HUD text var tgo = GameObject.Find("HUD_BonesText"); if (tgo != null) bonesText = tgo.GetComponent(); } void Update() { HandleMovement(); } void HandleMovement() { // WASD explicit as requested float h = 0f, v = 0f; if (Input.GetKey(KeyCode.W)) v += 1f; if (Input.GetKey(KeyCode.S)) v -= 1f; if (Input.GetKey(KeyCode.D)) h += 1f; if (Input.GetKey(KeyCode.A)) h -= 1f; Vector3 localMove = new Vector3(h, 0f, v).normalized; Vector3 worldMove = transform.TransformDirection(localMove) * moveSpeed; // preserve y velocity for gravity/jump rb.velocity = new Vector3(worldMove.x, rb.velocity.y, worldMove.z); // jump if (Input.GetKeyDown(KeyCode.Space) && IsGrounded()) { rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse); } } bool IsGrounded() { return Physics.Raycast(transform.position, Vector3.down, groundCheckDistance, groundMask); } void OnCollisionEnter(Collision collision) { // Coleta via colisão com ossos (prefab usa tag "Bone") if (collision.collider != null && collision.collider.CompareTag("Bone")) { bonesCollected++; UpdateHUD(); Vector3 respawnPos = collision.collider.transform.position; // destrói o osso coletado Destroy(collision.collider.gameObject); // Respawn simples: instancia um novo after delay StartCoroutine(RespawnBone(respawnPos, 5f)); } } IEnumerator RespawnBone(Vector3 pos, float delay) { yield return new WaitForSeconds(delay); // cria primitive capsule como novo osso GameObject bone = GameObject.CreatePrimitive(PrimitiveType.Capsule); bone.transform.position = pos + Vector3.up * 0.5f; bone.transform.localScale = new Vector3(0.3f, 0.8f, 0.3f); var rbB = bone.AddComponent(); rbB.mass = 0.3f; bone.tag = "Bone"; bone.name = "Bone_Respawned"; // small collider tweak var col = bone.GetComponent(); if (col) col.material = new PhysicMaterial() { bounciness = 0.2f, frictionCombine = PhysicMaterialCombine.Multiply }; } void UpdateHUD() { if (bonesText != null) bonesText.text = "Ossos: " + bonesCollected; } } // ---------- RUNTIME: CameraFollow ---------- public class CameraFollow : MonoBehaviour { public Transform target; public float smooth = 5f; public Vector3 offset = new Vector3(0, 4, -6); void LateUpdate() { if (target == null) return; Vector3 desired = target.position + offset; transform.position = Vector3.Lerp(transform.position, desired, smooth * Time.deltaTime); transform.LookAt(target.position + Vector3.up * 1.0f); } } // ---------- RUNTIME: SimpleDogAI (optional) ---------- public class SimpleDogAI : MonoBehaviour { public float detectRadius = 8f; public float moveSpeed = 3f; private Transform targetBone; void Update() { DetectBone(); if (targetBone != null) { Vector3 dir = (targetBone.position - transform.position).normalized; transform.position += dir * moveSpeed * Time.deltaTime; transform.LookAt(targetBone); } } void DetectBone() { Collider[] cols = Physics.OverlapSphere(transform.position, detectRadius); targetBone = null; foreach (var c in cols) { if (c.CompareTag("Bone")) { targetBone = c.transform; break; } } } } #if UNITY_EDITOR // ---------- EDITOR: Setup automático (roda só uma vez) ---------- [InitializeOnLoadMethod] static void AutoSetupOnce() { // Se já setupado, não faz nada string marker = "Assets/DogGame_SetupDone.txt"; if (File.Exists(marker)) return; // Run setup EditorApplication.delayCall += () => { // Criar pasta Assets/DogGameAssets opcional if (!AssetDatabase.IsValidFolder("Assets/DogGameAssets")) AssetDatabase.CreateFolder("Assets", "DogGameAssets"); CreateAnimatorController(); CreateBonePrefab(); CreateSceneObjects(); CreateHUD(); AssetDatabase.Refresh(); // cria arquivo marcador File.WriteAllText(marker, "setup done"); AssetDatabase.Refresh(); Debug.Log("[DogGame] Setup automático concluído."); }; } [MenuItem("DogGame/Run Setup Now")] public static void RunSetupNowMenu() { // Force run if needed string marker = "Assets/DogGame_SetupDone.txt"; if (File.Exists(marker)) { if (!EditorUtility.DisplayDialog("DogGame", "Setup já foi executado. Deseja forçar novamente?", "Sim", "Não")) return; File.Delete(marker); } AutoSetupOnce(); } static void CreateAnimatorController() { string path = "Assets/DogGameAssets/DogAnimator.controller"; if (File.Exists(path)) return; var controller = AnimatorController.CreateAnimatorControllerAtPath(path); controller.AddParameter("Speed", AnimatorControllerParameterType.Float); controller.AddParameter("IsGrounded", AnimatorControllerParameterType.Bool); // cria estados vazios (arraste clipes depois) var root = controller.layers[0].stateMachine; var idle = root.AddState("Idle"); var run = root.AddState("Run"); var jump = root.AddState("Jump"); // transições simples var t1 = idle.AddTransition(run); t1.hasExitTime = false; t1.AddCondition(AnimatorConditionMode.Greater, 0.1f, "Speed"); var t2 = run.AddTransition(idle); t2.hasExitTime = false; t2.AddCondition(AnimatorConditionMode.Less, 0.1f, "Speed"); var tj1 = idle.AddTransition(jump); tj1.AddCondition(AnimatorConditionMode.IfNot, 0, "IsGrounded"); var tj2 = run.AddTransition(jump); tj2.AddCondition(AnimatorConditionMode.IfNot, 0, "IsGrounded"); var tj3 = jump.AddTransition(idle); tj3.AddCondition(AnimatorConditionMode.If, 0, "IsGrounded"); AssetDatabase.SaveAssets(); } static void CreateBonePrefab() { string prefabPath = "Assets/DogGameAssets/Bone.prefab"; if (File.Exists(prefabPath)) return; GameObject bone = GameObject.CreatePrimitive(PrimitiveType.Capsule); bone.name = "Bone"; bone.transform.localScale = new Vector3(0.3f, 0.8f, 0.3f); var rb = bone.AddComponent(); rb.mass = 0.3f; // make collider phys material var col = bone.GetComponent(); if (col != null) col.material = new PhysicMaterial() { bounciness = 0.2f, frictionCombine = PhysicMaterialCombine.Multiply }; bone.tag = "Bone"; PrefabUtility.SaveAsPrefabAsset(bone, prefabPath); GameObject.DestroyImmediate(bone); } static void CreateSceneObjects() { // Create (or find) a root object GameObject root = GameObject.Find("DogGame_Root"); if (root == null) root = new GameObject("DogGame_Root"); // Create player GameObject player = GameObject.Find("DogPlayer"); if (player == null) { player = GameObject.CreatePrimitive(PrimitiveType.Capsule); player.name = "DogPlayer"; player.transform.position = new Vector3(0, 2, 0); // add components var rb = player.GetComponent(); if (rb == null) rb = player.AddComponent(); rb.constraints = RigidbodyConstraints.None; // add DogController if (player.GetComponent() == null) player.AddComponent(); // add camera target child GameObject camTarget = new GameObject("CameraTarget"); camTarget.transform.SetParent(player.transform); camTarget.transform.localPosition = new Vector3(0, 2, -5); player.transform.SetParent(root.transform); } // Create main camera if none if (Camera.main == null) { GameObject camGO = new GameObject("Main Camera"); camGO.tag = "MainCamera"; var cam = camGO.AddComponent(); camGO.AddComponent(); cam.transform.position = new Vector3(0, 6, -10); cam.transform.LookAt(player.transform); var follow = camGO.AddComponent(); follow.target = player.transform; camGO.transform.SetParent(root.transform); } else { // ensure CameraFollow attached and target set var c = Camera.main.gameObject; var follow = c.GetComponent(); if (follow == null) follow = c.AddComponent(); follow.target = player.transform; } // Create some bones in scene (instances of prefab) string prefabPath = "Assets/DogGameAssets/Bone.prefab"; GameObject bonePrefab = AssetDatabase.LoadAssetAtPath(prefabPath); if (bonePrefab != null) { for (int i = 0; i < 8; i++) { Vector3 pos = new Vector3(Random.Range(-8, 8), 1.0f, Random.Range(-8, 8)); GameObject b = (GameObject)PrefabUtility.InstantiatePrefab(bonePrefab); b.transform.position = pos; b.name = "Bone_Spawned_" + i; b.transform.SetParent(root.transform); } } else { // fallback: create primitives for (int i = 0; i < 8; i++) { Vector3 pos = new Vector3(Random.Range(-8, 8), 1.0f, Random.Range(-8, 8)); GameObject b = GameObject.CreatePrimitive(PrimitiveType.Capsule); b.transform.position = pos; b.transform.localScale = new Vector3(0.3f, 0.8f, 0.3f); var rbb = b.AddComponent(); rbb.mass = 0.3f; b.tag = "Bone"; b.name = "Bone_Spawned_Fallback_" + i; b.transform.SetParent(root.transform); } } // Create procedural city (grid of blocks) GameObject cityRoot = GameObject.Find("ProceduralCity"); if (cityRoot == null) { cityRoot = new GameObject("ProceduralCity"); cityRoot.transform.SetParent(root.transform); int grid = 8; float spacing = 14f; for (int x = -grid/2; x < grid/2; x++) { for (int z = -grid/2; z < grid/2; z++) { GameObject building = GameObject.CreatePrimitive(PrimitiveType.Cube); float h = Random.Range(4f, 25f); building.transform.position = new Vector3(x * spacing, h/2f, z * spacing); building.transform.localScale = new Vector3(10f, h, 10f); building.transform.SetParent(cityRoot.transform); // set layer to Default/ground mask optionally } } } } static void CreateHUD() { // If HUD already exists, skip GameObject existing = GameObject.Find("HUD_Canvas"); if (existing != null) return; // create canvas GameObject canvasGO = new GameObject("HUD_Canvas"); var canvas = canvasGO.AddComponent(); canvas.renderMode = UnityEngine.RenderMode.ScreenSpaceOverlay; canvasGO.AddComponent(); canvasGO.AddComponent(); // create text GameObject textGO = new GameObject("HUD_BonesText"); textGO.transform.SetParent(canvasGO.transform); var text = textGO.AddComponent(); text.font = Resources.GetBuiltinResource("Arial.ttf"); text.fontSize = 28; text.alignment = TextAnchor.UpperRight; text.text = "Ossos: 0"; RectTransform rt = text.GetComponent(); rt.anchorMin = new Vector2(1, 1); rt.anchorMax = new Vector2(1, 1); rt.pivot = new Vector2(1, 1); rt.anchoredPosition = new Vector2(-12, -12); rt.sizeDelta = new Vector2(300, 60); // Ensure player DogController finds this Text at runtime (it looks for object named HUD_BonesText) EditorUtility.SetDirty(canvasGO); } #endif }

Enjoying this? A quick like helps keep it online longer.

Content Expiring Soon

This content will be deleted in less than 24 hours. If you like it, you can extend its lifetime to keep it available.

0 likes
0 views
12 days left
Like what you see? Create your own
0
0
12d