Hi,
I am trying to create a scrip that can be attached to a game object, has a variable “maxPoints” which when changed in the editor, I want it to draw the new sprites in the editor (and of course, create the sprites at runtime).
I’ve created a script that creates the sprites in the editor when I set the variable, but if I decrease the variable, it doesn’t get rid of the old sprites, it just gives a warning “SendMessage cannot be called during Awake, CheckConsistency, or OnValidate (Lane0L1: OnDidAddComponent)”.
Script:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SocialPlatforms.Impl;
[ExecuteInEditMode]
public class BottomBumperManager : MonoBehaviour
{
[SerializeField]
public GameObject exitAnim;
[SerializeField]
public Sprite emptyPoint;
[SerializeField]
public Sprite fullPoint;
[SerializeField]
public int maxPoints = 3;
[SerializeField]
public int laneNumber = 0;
private int currentScore = 0;
private List<GameObject> markers = new List<GameObject>();
private List<GameObject> markersToDestroy = new List<GameObject>();
void Start()
{
if (Application.isPlaying)
{
CreateMarkers();
}
}
void CreateMarkers()
{
Debug.Log("Creating Markers");
// Manage old markers
if (!Application.isPlaying)
{
// Clear any existing markers for editing
markersToDestroy.AddRange(markers);
markers.Clear();
}
// Create and position markers
for (int i = 0; i < maxPoints; i++)
{
GameObject marker = new GameObject($"Lane{laneNumber}L{i + 1}");
= transform; // Set this as the parent
SpriteRenderer spriteRenderer = marker.AddComponent<SpriteRenderer>();
spriteRenderer.sprite = emptyPoint;
// Position marker vertically
var width = transform.localScale.x / 4;
Vector3 currentPosition = transform.position;
currentPosition.y += ((transform.localScale.x / 2) * i);
marker.transform.position = currentPosition;
marker.transform.localScale = new Vector3(width, width, 1);
markers.Add(marker);
}
// Start coroutine to destroy old markers after the frame is rendered
StartCoroutine(DestroyOldMarkers());
}
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.name == "Ball")
{
//Reduce bounce to stop ball leaving it's lane
var rb2d = collision.gameObject.GetComponent<Rigidbody2D>();
rb2d.sharedMaterial.bounciness = 0.001f;
//Report back that drop is complete
GameManager.Instance.DropComplete();
//Start exit animation if one is attached
if (exitAnim != null)
{
var _exitAnim = Instantiate(exitAnim);
_exitAnim.transform.position = collision.gameObject.transform.position;
}
//Increment lane score
currentScore++;
//Increment lane marker
//var marker = GameObject.Find($"Lane{laneNumber}L{currentScore}");
var marker = markers.Where(p => == $"Lane{laneNumber}L{currentScore}").FirstOrDefault();
if (marker != null && maxPoints > 0)
{
var spriteRender = marker.GetComponent<SpriteRenderer>();
spriteRender.sprite = fullPoint;
}
//Destroy ball
Destroy(collision.gameObject);
//Check if we are at our max
if (currentScore == maxPoints)
{
Debug.Log("Done");
}
}
}
void OnValidate()
{
int currentMarkerCount = markers.Count;
if (currentMarkerCount != maxPoints)
{
CreateMarkers();
}
}
IEnumerator DestroyOldMarkers()
{
yield return new WaitForEndOfFrame();
foreach (var marker in markersToDestroy)
{
Destroy(marker);
}
markersToDestroy.Clear();
}
}
I am sure I am doing a whole long wrong here, but any help would be appreciated.