nahraná dosavadní verze hry

This commit is contained in:
2025-06-23 16:30:18 +02:00
commit 1cdde31d73
639 changed files with 255998 additions and 0 deletions

View File

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

View File

@@ -0,0 +1,573 @@
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class MapGenManager : MonoBehaviour
{
[Header("Room Prefabs")]
[SerializeField] private List<GameObject> mapPrefab = new List<GameObject>();
[SerializeField] private GameObject StartPoint;
[SerializeField] private GameObject EndPoint;
[Header("Player")]
[SerializeField] private GameObject Player;
[Header("Corridor Prefabs")]
[SerializeField] private GameObject CorridorStraight;
[SerializeField] private GameObject CorridorL;
[SerializeField] private GameObject CorridorT;
[SerializeField] private GameObject CorridorCross;
[SerializeField] private GameObject CorridorEnd;
[Header("Generation Settings")]
[SerializeField] private float minRoomDistance = 30f;
[SerializeField] private float maxRoomDistance = 50f;
[SerializeField] private float corridorWidth = 5f;
private List<Vector3> roomPositions = new List<Vector3>();
private List<GameObject> placedRooms = new List<GameObject>();
void Start()
{
MapGen();
}
private void MapGen()
{
roomPositions.Clear();
placedRooms.Clear();
// Start position should be aligned to grid
Vector3 startPos = new Vector3(0, 0, 0); // Grid aligned at origin
GameObject startPoint = Instantiate(StartPoint, startPos, Quaternion.identity, transform);
roomPositions.Add(startPos);
placedRooms.Add(startPoint);
GameObject player = Instantiate(Player, new Vector3(startPos.x, 1, startPos.z), Quaternion.identity, transform);
int roomCount = Random.Range(3, 7);
for (int i = 0; i < roomCount; i++)
{
Vector3 roomPos = GetRandomGridPosition();
GameObject roomPrefab = mapPrefab[Random.Range(0, mapPrefab.Count)];
GameObject room = Instantiate(roomPrefab, roomPos, Quaternion.identity, transform);
placedRooms.Add(room);
roomPositions.Add(roomPos);
}
GameObject endPoint = Instantiate(EndPoint, GetRandomGridPosition(), Quaternion.identity, transform);
roomPositions.Add(endPoint.transform.position);
placedRooms.Add(endPoint);
// Generate corridors to connect rooms
GenerateCorridors();
// Add some dead ends for more dynamic layouts
AddDeadEndCorridors();
}
private void GenerateCorridors()
{
// Create a minimum spanning tree to ensure all rooms are connected
List<(int, int)> edges = CreateMinimumSpanningTree();
// Place corridors between connected rooms
foreach (var edge in edges)
{
ConnectRoomsWithCorridor(roomPositions[edge.Item1], roomPositions[edge.Item2]);
}
}
private List<(int, int)> CreateMinimumSpanningTree()
{
// Using Prim's algorithm to generate a minimum spanning tree
List<(int, int)> mstEdges = new List<(int, int)>();
List<int> connectedNodes = new List<int>();
List<int> unconnectedNodes = new List<int>();
// Start with node 0 (start room)
for (int i = 0; i < roomPositions.Count; i++)
{
unconnectedNodes.Add(i);
}
// Start with first node
connectedNodes.Add(unconnectedNodes[0]);
unconnectedNodes.RemoveAt(0);
// Continue until all nodes are connected
while (unconnectedNodes.Count > 0)
{
float minDistance = float.MaxValue;
int closestConnected = -1;
int closestUnconnected = -1;
// Find shortest edge between a connected and unconnected node
foreach (int connected in connectedNodes)
{
foreach (int unconnected in unconnectedNodes)
{
float distance = Vector3.Distance(roomPositions[connected], roomPositions[unconnected]);
if (distance < minDistance)
{
minDistance = distance;
closestConnected = connected;
closestUnconnected = unconnected;
}
}
}
// Add the edge to our MST
mstEdges.Add((closestConnected, closestUnconnected));
// Move the node from unconnected to connected
connectedNodes.Add(closestUnconnected);
unconnectedNodes.Remove(closestUnconnected);
}
return mstEdges;
}
private void ConnectRoomsWithCorridor(Vector3 startRoom, Vector3 endRoom)
{
// Calculate the grid-based path between rooms
List<Vector3> path = CalculateGridPath(startRoom, endRoom);
// Place corridor pieces along the path
for (int i = 0; i < path.Count - 1; i++)
{
PlaceCorridorSegment(path[i], path[i + 1]);
}
}
private List<Vector3> CalculateGridPath(Vector3 start, Vector3 end)
{
List<Vector3> path = new List<Vector3>();
path.Add(start);
// Determine if we go horizontal first or vertical first (50/50 chance)
bool horizontalFirst = Random.value < 0.5f;
Vector3 current = start;
if (horizontalFirst)
{
// Move horizontally first, then vertically
while (Mathf.Abs(current.x - end.x) >= 5)
{
float step = current.x < end.x ? 5 : -5;
current = new Vector3(current.x + step, 0, current.z);
path.Add(current);
}
while (Mathf.Abs(current.z - end.z) >= 5)
{
float step = current.z < end.z ? 5 : -5;
current = new Vector3(current.x, 0, current.z + step);
path.Add(current);
}
}
else
{
// Move vertically first, then horizontally
while (Mathf.Abs(current.z - end.z) >= 5)
{
float step = current.z < end.z ? 5 : -5;
current = new Vector3(current.x, 0, current.z + step);
path.Add(current);
}
while (Mathf.Abs(current.x - end.x) >= 5)
{
float step = current.x < end.x ? 5 : -5;
current = new Vector3(current.x + step, 0, current.z);
path.Add(current);
}
}
// Add the end position if it's not already there
if (Vector3.Distance(current, end) >= 5)
{
path.Add(end);
}
return path;
}
private void PlaceCorridorSegment(Vector3 start, Vector3 end)
{
// Determine corridor type based on connecting rooms
Vector3 direction = end - start;
GameObject corridorPrefab = CorridorStraight; // Default to straight
Quaternion rotation = Quaternion.identity;
Vector3 position = (start + end) / 2;
// Calculate direction for rotation
if (direction.x > 0) // East
{
rotation = Quaternion.Euler(0, 90, 0);
}
else if (direction.x < 0) // West
{
rotation = Quaternion.Euler(0, 90, 0);
}
else if (direction.z > 0) // North
{
rotation = Quaternion.Euler(0, 0, 0);
}
else if (direction.z < 0) // South
{
rotation = Quaternion.Euler(0, 0, 0);
}
// Check if this segment is part of a turn, T-junction, or crossing
List<Direction> connectingDirections = GetConnectingDirections(end);
// Determine corridor type and rotation based on connections
if (connectingDirections.Count == 1) // Straight corridor or dead end
{
corridorPrefab = CorridorStraight;
}
else if (connectingDirections.Count == 2)
{
// Check if it's an L-turn
if (IsLTurn(direction, connectingDirections))
{
corridorPrefab = CorridorL;
// Adjust rotation for L-turn
rotation = GetLTurnRotation(direction, connectingDirections);
}
}
else if (connectingDirections.Count == 3) // T-junction
{
corridorPrefab = CorridorT;
// Adjust rotation for T-junction
rotation = GetTJunctionRotation(direction, connectingDirections);
}
else if (connectingDirections.Count >= 4) // Cross junction
{
corridorPrefab = CorridorCross;
}
Instantiate(corridorPrefab, position, rotation, transform);
}
private enum Direction { North, East, South, West }
private List<Direction> GetConnectingDirections(Vector3 position)
{
// Check which directions have corridors or rooms from this position
List<Direction> connections = new List<Direction>();
// Check in each cardinal direction
Vector3[] offsets = new Vector3[] {
new Vector3(0, 0, 5), // North
new Vector3(5, 0, 0), // East
new Vector3(0, 0, -5), // South
new Vector3(-5, 0, 0) // West
};
Direction[] directions = new Direction[] {
Direction.North,
Direction.East,
Direction.South,
Direction.West
};
for (int i = 0; i < offsets.Length; i++)
{
Vector3 checkPos = position + offsets[i];
// Check if there's a room at this position
bool hasConnection = roomPositions.Any(rp => Vector3.Distance(rp, checkPos) < 2.5f);
// If no room, check for corridor (simplified - in a full implementation,
// you'd track placed corridors separately)
if (!hasConnection)
{
// For simplicity, assume there's a corridor if it's part of a path we've calculated
// In a complete implementation, you'd track corridor positions
}
if (hasConnection)
{
connections.Add(directions[i]);
}
}
return connections;
}
private bool IsLTurn(Vector3 incomingDirection, List<Direction> connections)
{
// Check if connections form an L shape (90-degree turn)
if (connections.Count != 2) return false;
Direction incoming = VectorToDirection(incomingDirection);
Direction opposite = GetOppositeDirection(incoming);
// If one of the connections is opposite to the incoming direction,
// then it's a straight corridor, not an L-turn
return !connections.Contains(opposite);
}
private Direction VectorToDirection(Vector3 vector)
{
if (vector.x > 0) return Direction.East;
if (vector.x < 0) return Direction.West;
if (vector.z > 0) return Direction.North;
return Direction.South;
}
private Direction GetOppositeDirection(Direction dir)
{
switch (dir)
{
case Direction.North: return Direction.South;
case Direction.East: return Direction.West;
case Direction.South: return Direction.North;
case Direction.West: return Direction.East;
default: return Direction.North;
}
}
private Quaternion GetLTurnRotation(Vector3 incomingDirection, List<Direction> connections)
{
// Calculate rotation for L-turns based on the directions it connects
Direction incoming = VectorToDirection(incomingDirection);
// Find the other direction (not the incoming and not the opposite of incoming)
Direction other = connections.Find(d => d != incoming && d != GetOppositeDirection(incoming));
switch (incoming)
{
case Direction.North:
return other == Direction.East ? Quaternion.Euler(0, 0, 0) : Quaternion.Euler(0, 270, 0);
case Direction.East:
return other == Direction.North ? Quaternion.Euler(0, 90, 0) : Quaternion.Euler(0, 0, 0);
case Direction.South:
return other == Direction.East ? Quaternion.Euler(0, 270, 0) : Quaternion.Euler(0, 180, 0);
case Direction.West:
return other == Direction.North ? Quaternion.Euler(0, 180, 0) : Quaternion.Euler(0, 90, 0);
default:
return Quaternion.identity;
}
}
private Quaternion GetTJunctionRotation(Vector3 incomingDirection, List<Direction> connections)
{
// Calculate rotation for T-junctions
Direction incoming = VectorToDirection(incomingDirection);
Direction opposite = GetOppositeDirection(incoming);
// If the connection doesn't include the opposite direction, the "T" points in that direction
if (!connections.Contains(opposite))
{
switch (opposite)
{
case Direction.North: return Quaternion.Euler(0, 0, 0);
case Direction.East: return Quaternion.Euler(0, 90, 0);
case Direction.South: return Quaternion.Euler(0, 180, 0);
case Direction.West: return Quaternion.Euler(0, 270, 0);
}
}
// If it does contain the opposite, find the missing direction
Direction[] allDirections = new Direction[] { Direction.North, Direction.East, Direction.South, Direction.West };
Direction missing = allDirections.First(d => !connections.Contains(d));
switch (missing)
{
case Direction.North: return Quaternion.Euler(0, 180, 0);
case Direction.East: return Quaternion.Euler(0, 270, 0);
case Direction.South: return Quaternion.Euler(0, 0, 0);
case Direction.West: return Quaternion.Euler(0, 90, 0);
default: return Quaternion.identity;
}
}
private void AddDeadEndCorridors()
{
// Add some random dead ends for more interesting level design
int deadEndCount = Random.Range(1, 4); // 1-3 dead ends
for (int i = 0; i < deadEndCount; i++)
{
// Pick a random room to extend from
int roomIndex = Random.Range(0, roomPositions.Count);
Vector3 roomPos = roomPositions[roomIndex];
// Pick a random direction
Vector3[] directions = new Vector3[] {
new Vector3(5, 0, 0), // East
new Vector3(-5, 0, 0), // West
new Vector3(0, 0, 5), // North
new Vector3(0, 0, -5) // South
};
Vector3 direction = directions[Random.Range(0, directions.Length)];
// Create a dead end corridor (1-3 segments long)
int segmentCount = Random.Range(1, 4);
Vector3 currentPos = roomPos;
for (int j = 0; j < segmentCount; j++)
{
Vector3 nextPos = currentPos + direction;
// Make sure we're not placing corridors where rooms exist
bool canPlace = true;
foreach (Vector3 roomPosition in roomPositions)
{
if (Vector3.Distance(nextPos, roomPosition) < 5)
{
canPlace = false;
break;
}
}
if (canPlace)
{
PlaceCorridorSegment(currentPos, nextPos);
currentPos = nextPos;
}
else
{
break;
}
}
// Place an end cap at the last position if it's not overlapping with a room
bool endCapCanBePlaced = true;
foreach (Vector3 roomPosition in roomPositions)
{
if (Vector3.Distance(currentPos, roomPosition) < 5)
{
endCapCanBePlaced = false;
break;
}
}
if (endCapCanBePlaced && segmentCount > 0)
{
// Calculate rotation based on direction
Quaternion rotation = Quaternion.identity;
if (direction.x > 0) rotation = Quaternion.Euler(0, 90, 0);
else if (direction.x < 0) rotation = Quaternion.Euler(0, 270, 0);
else if (direction.z > 0) rotation = Quaternion.Euler(0, 0, 0);
else if (direction.z < 0) rotation = Quaternion.Euler(0, 180, 0);
Instantiate(CorridorEnd, currentPos, rotation, transform);
}
}
}
private Vector3 GetRandomGridPosition()
{
Vector3 lastRoomPos = roomPositions[roomPositions.Count - 1];
// Calculate min and max distances in grid units (multiples of 5)
int minGridDistance = Mathf.CeilToInt(minRoomDistance / 5);
int maxGridDistance = Mathf.FloorToInt(maxRoomDistance / 5);
// Get random grid cell offset
int xGridOffset = 0;
int zGridOffset = 0;
Vector3 roomPos = Vector3.zero;
// Make sure the position is valid
int attempts = 0;
int maxAttempts = 100; // Prevent infinite loops
do {
// Generate random offsets directly as grid units
xGridOffset = Random.Range(-maxGridDistance, maxGridDistance + 1);
zGridOffset = Random.Range(-maxGridDistance, maxGridDistance + 1);
// Ensure we respect minimum distance
if (Mathf.Abs(xGridOffset) < minGridDistance && Mathf.Abs(zGridOffset) < minGridDistance)
{
// Force minimum distance by picking a direction
if (Random.value < 0.5f)
xGridOffset = Random.value < 0.5f ? minGridDistance : -minGridDistance;
else
zGridOffset = Random.value < 0.5f ? minGridDistance : -minGridDistance;
}
// Convert grid units to world position (multiply by 5)
roomPos = new Vector3(
lastRoomPos.x + (xGridOffset * 5),
0,
lastRoomPos.z + (zGridOffset * 5)
);
attempts++;
} while (!IsValidPos(roomPos) && attempts < maxAttempts);
// If we couldn't find a valid position, use fallback
if (attempts >= maxAttempts)
{
Debug.LogWarning("Couldn't find valid room position after " + maxAttempts + " attempts. Using best approximation.");
roomPos = FindNearestValidGridPosition(lastRoomPos);
}
return roomPos;
}
private Vector3 FindNearestValidGridPosition(Vector3 startPos)
{
// Define min and max grid distances in grid units (not world units)
int minGridDistance = Mathf.CeilToInt(minRoomDistance / 5);
int maxGridDistance = Mathf.FloorToInt(maxRoomDistance / 5);
// Check each grid distance in increasing order
for (int distance = minGridDistance; distance <= maxGridDistance; distance++)
{
// Try cardinal directions first (more likely to have space)
int[] directions = { distance, -distance };
// Try horizontal directions
foreach (int x in directions)
{
Vector3 testPos = new Vector3(startPos.x + (x * 5), 0, startPos.z);
if (IsValidPos(testPos))
return testPos;
}
// Try vertical directions
foreach (int z in directions)
{
Vector3 testPos = new Vector3(startPos.x, 0, startPos.z + (z * 5));
if (IsValidPos(testPos))
return testPos;
}
// Try diagonals
foreach (int x in directions)
{
foreach (int z in directions)
{
Vector3 testPos = new Vector3(startPos.x + (x * 5), 0, startPos.z + (z * 5));
if (IsValidPos(testPos))
return testPos;
}
}
}
// If all else fails, return a position at minimum distance
return new Vector3(startPos.x + (minGridDistance * 5), 0, startPos.z);
}
private bool IsValidPos(Vector3 pos)
{
foreach (Vector3 roomPos in roomPositions)
{
if (Vector3.Distance(pos, roomPos) < minRoomDistance)
{
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: fba07e5a285f4d84f93955f44f02c76c

View File

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

View File

@@ -0,0 +1,23 @@
using UnityEngine;
using UnityEngine.SceneManagement;
public class MenuController : MonoBehaviour
{
public GameObject settingsMenu;
public void PlayButton()
{
SceneManager.LoadScene("Podzemi");
}
public void SettingButtonn()
{
settingsMenu.SetActive(true);
gameObject.SetActive(false);
}
public void ExitButtonn()
{
Application.Quit();
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4918739cfb6195f4e89c42e7880eb9d9

View File

@@ -0,0 +1,82 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.UI;
public class SettingsMenu : MonoBehaviour
{
public AudioMixer audioMixer;
public Slider volumeSlider;
public Toggle fullscreenToggle;
public TMP_Dropdown qualityDropdown;
public TMP_Dropdown resolutionDropdown;
public GameObject mainMenu;
[SerializeField] private TextMeshProUGUI volumeText;
Resolution[] resolutions;
int currentResolutionIndex;
void Start()
{
if (volumeSlider != null)
{
volumeSlider.onValueChanged.AddListener(setVolume);
}
if (fullscreenToggle != null)
{
fullscreenToggle.onValueChanged.AddListener(setFullscreen);
}
if (qualityDropdown != null)
{
qualityDropdown.onValueChanged.AddListener(setQuality);
}
if (resolutionDropdown != null)
{
resolutions = Screen.resolutions;
resolutionDropdown.ClearOptions();
List<string> options = new List<string>();
for (int i = 0; i < resolutions.Length; i++)
{
string option = resolutions[i].width + " x " + resolutions[i].height;
options.Add(option);
if(resolutions[i].width == Screen.width && resolutions[i].height == Screen.height) currentResolutionIndex = i;
}
resolutionDropdown.AddOptions(options);
resolutionDropdown.value = currentResolutionIndex;
resolutionDropdown.RefreshShownValue();
resolutionDropdown.onValueChanged.AddListener(setResolution);
}
}
public void ContinueButton()
{
gameObject.SetActive(false);
mainMenu.SetActive(true);
}
public void setVolume(float vol)
{
float mixerVolume = Mathf.Lerp(-80f, 0f, vol);
audioMixer.SetFloat("Volume", mixerVolume);
volumeText.text = Mathf.RoundToInt(vol * 100) + "%";
}
public void setQuality(int qualityIndex)
{
QualitySettings.SetQualityLevel(qualityIndex);
}
public void setFullscreen(bool isFullscreen)
{
Screen.fullScreen = isFullscreen;
}
public void setResolution(int resolutionIndex)
{
Screen.SetResolution(resolutions[resolutionIndex].width, resolutions[resolutionIndex].height, FullScreenMode.FullScreenWindow);
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e6c70300d39791a468efbbdaecd64232

View File

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

View File

@@ -0,0 +1,19 @@
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
public Transform target; // The player's transform to follow
public Vector3 offset = new Vector3(0f, 2f, -5f); // Offset from the target
void Update()
{
if (target == null)
return;
// Update the camera's position to follow the target with an offset
transform.position = target.position + offset;
// Make the camera look at the target
transform.LookAt(target);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 29b10d799791ba548b694b2f7f25701b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,79 @@
using UnityEngine;
public class CameraManager : MonoBehaviour
{
[Header("Target Settings")]
public Transform target;
[Header("Position Settings")]
public Vector3 offset = new Vector3(0f, 10f, -5f);
public float followSpeed = 10f;
[Header("Zoom Settings")]
public float zoomSpeed = 5f;
public float minZoomHeight = 5f;
public float maxZoomHeight = 15f;
public float zoomZRatio = 0.5f; // How much Z changes relative to Y when zooming
// Current zoom level (0 = min zoom, 1 = max zoom)
private float zoomLevel = 0.5f;
// Fixed camera rotation
public Vector3 cameraRotation = new Vector3(45f, 0f, 0f);
void Start()
{
if (target == null)
{
Debug.LogWarning("No target assigned to CameraManager!");
return;
}
// Set initial rotation
transform.eulerAngles = cameraRotation;
// Position the camera immediately at start
UpdateCameraPosition(false);
}
void LateUpdate()
{
if (target == null)
return;
// Handle zoom input
float scrollInput = Input.GetAxis("Mouse ScrollWheel");
if (scrollInput != 0)
{
// Update zoom level
zoomLevel = Mathf.Clamp01(zoomLevel - scrollInput * zoomSpeed * Time.deltaTime);
}
// Update camera position with smoothing
UpdateCameraPosition(true);
// Ensure the camera rotation stays fixed
transform.eulerAngles = cameraRotation;
}
void UpdateCameraPosition(bool smooth)
{
// Calculate height and Z offset based on zoom level
float height = Mathf.Lerp(minZoomHeight, maxZoomHeight, zoomLevel);
float zOffset = -Mathf.Lerp(minZoomHeight * zoomZRatio, maxZoomHeight * zoomZRatio, zoomLevel);
// Create the target position
Vector3 targetPosition = target.position + new Vector3(0, height, zOffset);
if (smooth)
{
// Smoothly move towards the target position
transform.position = Vector3.Lerp(transform.position, targetPosition, followSpeed * Time.deltaTime);
}
else
{
// Instantly set position
transform.position = targetPosition;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a7d89920cdf28dc4b87af26ee136cf12

View File

@@ -0,0 +1,27 @@
using UnityEngine;
public class CameraZoom : MonoBehaviour
{
public float zoomSpeed = 10f; // Speed of zooming
public float minZoom = 5f; // Minimum zoom distance
public float maxZoom = 20f; // Maximum zoom distance
private Camera cam;
void Start()
{
cam = GetComponent<Camera>(); // Get the Camera component attached to the GameObject
}
void Update()
{
// Get the scroll wheel input
float scrollInput = Input.GetAxis("Mouse ScrollWheel");
// Calculate the new field of view (FOV)
float newFOV = cam.fieldOfView - scrollInput * zoomSpeed;
// Clamp the FOV to be within the min and max zoom distances
cam.fieldOfView = Mathf.Clamp(newFOV, minZoom, maxZoom);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6ba5303a34820d54f953de5d92f56656
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,53 @@
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float moveSpeed = 5f;
public float sprintSpeed = 10f;
public float gravity = -9.81f;
public float rotationSpeed = 10f;
private CharacterController controller;
private Vector3 velocity;
void Start()
{
controller = GetComponent<CharacterController>();
}
void FixedUpdate()
{
HandleMovement();
ApplyGravity();
}
void HandleMovement()
{
float moveX = Input.GetAxisRaw("Horizontal");
float moveZ = Input.GetAxisRaw("Vertical");
Vector3 move = new Vector3(moveX, 0, moveZ).normalized;
if (move.magnitude >= 0.1f)
{
float currentSpeed = Input.GetKey(KeyCode.LeftShift) ? sprintSpeed : moveSpeed;
Quaternion targetRotation = Quaternion.LookRotation(move);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.fixedDeltaTime);
controller.Move(move * currentSpeed * Time.fixedDeltaTime);
}
}
void ApplyGravity()
{
if (IsGrounded() && velocity.y < 0) velocity.y = -2f;
velocity.y += gravity * Time.fixedDeltaTime;
controller.Move(velocity * Time.fixedDeltaTime);
}
bool IsGrounded()
{
float groundDistance = 0.2f;
return Physics.Raycast(transform.position, Vector3.down, groundDistance);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1f70538d2e61bdb4786c9b951596ecb9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,53 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovementJump : MonoBehaviour
{
public CharacterController charControl;
public float speed = 12f;
public float gravity = -9.81f;
public float jumpHeight = 3f;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
private Vector3 velocity;
private bool isGrounded;
void Start()
{
}
void Update()
{
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if(isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * y;
charControl.Move(move * speed * Time.deltaTime);
if(Input.GetButtonDown("Jump") && isGrounded)
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
velocity.y += gravity * Time.deltaTime;
charControl.Move(velocity * Time.deltaTime);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dd49eadc2a40d404998ce4946886e88c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: