Hi there hello,
I’m trying to create a prefab spawning script that when the player clicks it will spawn a prefab but it can only spawn the prefab on a surface. However, my code below has a problem where it keeps thinking that the prefab is not being spawned on a valid surface. How do I fix this?
Here is my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnPrefab : MonoBehaviour
{
public GameObject spawnPrefab;
public float spawnDistance = 2.0f; // Adjust this distance as needed
void Update()
{
if (Input.GetMouseButtonDown(0)) // Left mouse button is pressed
{
SpawnPrefabInDirection();
}
}
void SpawnPrefabInDirection()
{
// Get the camera's position and direction
Camera mainCamera = Camera.main;
Vector3 cameraPosition = mainCamera.transform.position;
Vector3 cameraDirection = mainCamera.transform.forward;
// Calculate the spawn position in front of the camera
Vector3 spawnPosition = cameraPosition + cameraDirection * spawnDistance;
// Raycast to determine the surface normal in both directions
RaycastHit hitDown;
Quaternion rotation; // Declare the rotation variable
RaycastHit hitForward = new RaycastHit(); // Initialize the hitForward variable
if (Physics.Raycast(cameraPosition, Vector3.down, out hitDown) || Physics.Raycast(cameraPosition, cameraDirection, out hitForward))
{
if (hitDown.collider != null || hitForward.collider != null)
{
// Choose the hit point that is closest to the camera
if (Vector3.Distance(cameraPosition, hitDown.point) < Vector3.Distance(cameraPosition, hitForward.point))
{
spawnPosition = hitDown.point; // Set the spawn position to the ground hit point
rotation = Quaternion.FromToRotation(Vector3.up, hitDown.normal);
}
else
{
spawnPosition = hitForward.point; // Set the spawn position to the forward hit point
rotation = Quaternion.LookRotation(hitForward.normal, Vector3.up);
}
// Check if there's a collider beneath the spawn point
if (IsSpawnPointValid(spawnPosition))
{
Debug.Log("Spawn point is valid. Spawning at " + spawnPosition);
GameObject newPrefabInstance = Instantiate(spawnPrefab, spawnPosition, rotation);
}
else
{
Debug.Log("Spawn point is not valid.");
}
}
}
else
{
Debug.Log("No surface hit.");
}
}
bool IsSpawnPointValid(Vector3 spawnPoint)
{
RaycastHit hit;
if (Physics.Raycast(spawnPoint, Vector3.down, out hit, 1.0f)) // Use a raycast distance (e.g., 1.0f)
{
return true; // A collider is beneath the spawn point
}
return false; // No collider is found beneath the spawn point
}
}