Game Development Asked by Shamen Raze on January 17, 2021
This is the spawn script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// An object spawner
/// </summary>
public class SpawnObject : MonoBehaviour
{
#region Variables
// needed for spawning
[SerializeField]
GameObject spawnObject;
[SerializeField]
GameObject plane;
// spawn control
const float MinSpawnDelay = 0.1f;
const float MaxSpawnDelay = 0.5f;
Timer spawnTimer;
// spawn location support
float randomX;
float randomY;
float randomZ;
#endregion
#region Methods
/// <summary>
/// Use this for initialization
/// </summary>
void Start()
{
plane = GameObject.FindWithTag("Plane");
// save spawn boundaries for efficiency
float randomX = Random.Range (plane.transform.position.x - plane.transform.localScale.x / 2, plane.transform.position.x + plane.transform.localScale.x / 2);
float randomY = Random.Range (plane.transform.position.y - plane.transform.localScale.y / 2, plane.transform.position.y + plane.transform.localScale.y / 2);
float randomZ = Random.Range (plane.transform.position.y - plane.transform.localScale.z / 2, plane.transform.position.y + plane.transform.localScale.z / 2);
// create and start timer
spawnTimer = gameObject.AddComponent<Timer>();
spawnTimer.Duration = Random.Range(MinSpawnDelay, MaxSpawnDelay);
spawnTimer.Run();
}
/// <summary>
/// Update is called once per frame
/// </summary>
void Update()
{
// check for time to spawn a new enemy
if (spawnTimer.Finished)
{
objectSpawn();
// change spawn timer duration and restart
spawnTimer.Duration = Random.Range(MinSpawnDelay, MaxSpawnDelay);
spawnTimer.Run();
}
}
/// <summary>
/// Spawns an object at a random location on a plane
/// </summary>
void objectSpawn()
{
// generate random location and create new object
Vector3 randomPosition = GetARandomPos(plane);
Instantiate<GameObject>(spawnObject, randomPosition, Quaternion.identity);
}
/// <summary>
/// Return random position on the plane
/// </summary>
public Vector3 GetARandomPos(GameObject plane){
Mesh planeMesh = plane.GetComponent<MeshFilter>().mesh;
Bounds bounds = planeMesh.bounds;
float minX = plane.transform.position.x - plane.transform.localScale.x * bounds.size.x * 0.5f;
float minZ = plane.transform.position.z - plane.transform.localScale.z * bounds.size.z * 0.5f;
Vector3 newVec = new Vector3(Random.Range (minX, -minX),
plane.transform.position.y,
Random.Range (minZ, -minZ));
return newVec;
}
#endregion
}
The object script I called it Objectsp :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// A enemy
/// </summary>
public class Objectsp : MonoBehaviour
{
#region Variables
// death support
const float EnemyLifespanSeconds = 10;
Timer deathTimer;
#endregion
/// <summary>
/// Use this for initialization
/// </summary>
void Start()
{
// create and start timer
deathTimer = gameObject.AddComponent<Timer>();
deathTimer.Duration = EnemyLifespanSeconds;
deathTimer.Run();
}
/// <summary>
/// Update is called once per frame
/// </summary>
void Update()
{
// destroy enemy if death timer finished
if(deathTimer){
if (deathTimer.Finished)
{
Destroy(gameObject);
}
}
}
}
And the timer script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// A timer
/// </summary>
public class Timer : MonoBehaviour
{
#region Variables
// timer duration
float totalSeconds = 0;
// timer execution
float elapsedSeconds = 0;
bool running = false;
// support for Finished property
bool started = false;
#endregion
#region Properties
/// <summary>
/// Sets the duration of the timer
/// The duration can only be set if the timer isn't currently running
/// </summary>
/// <value>duration</value>
public float Duration
{
set
{
if (!running)
{
totalSeconds = value;
}
}
}
/// <summary>
/// Gets whether or not the timer has finished running
/// This property returns false if the timer has never been started
/// </summary>
/// <value>true if finished; otherwise, false.</value>
public bool Finished
{
get { return started && !running; }
}
/// <summary>
/// Gets whether or not the timer is currently running
/// </summary>
/// <value>true if running; otherwise, false.</value>
public bool Running
{
get { return running; }
}
#endregion
#region Methods
/// <summary>
/// Update is called once per frame
/// </summary>
void Update()
{
// update timer and check for finished
if (running)
{
elapsedSeconds += Time.deltaTime;
if (elapsedSeconds >= totalSeconds)
{
running = false;
}
}
}
/// <summary>
/// Runs the timer
/// Because a timer of 0 duration doesn't really make sense,
/// the timer only runs if the total seconds is larger than 0
/// This also makes sure the consumer of the class has actually
/// set the duration to something higher than 0
/// </summary>
public void Run()
{
// only run with valid duration
if (totalSeconds > 0)
{
started = true;
running = true;
elapsedSeconds = 0;
}
}
#endregion
}
This is the scene and settings screenshot, and since the plane is not at 0,0,0 the spawn objects are not inside the plane area.
If the plane is at 0,0,0 it will work fine but I want it to work also if the plane is not at 0,0,0 and also to use height.
On the Plane Spawner I attached the Spawn Object script and on the PlanePrefab the Objectsp and the Timer scripts.
You need to create or move the spawn point to the position you want - set the spawn point to the correct transform.position and it will spawn correctly. The plane spawner is at 0, 0, 0 - and it's spawning correctly - you need to move it to be at the location you want to spawn at (x, y, z).
Answered by Chris Norman on January 17, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP