Randomized Object/Material Scripts

Discussion in 'Player Created Resources' started by Sir Korvash, Dec 26, 2015.

Thread Status:
Not open for further replies.
  1. Sir Korvash

    Sir Korvash Avatar

    Messages:
    257
    Likes Received:
    699
    Trophy Points:
    40
    Gender:
    Male
    Location:
    Canada
    Hey all,

    Been a while since I was active on the forums, and been even longer since I did anything constructive. So figured it was time to do something constructive, and possibly useful to both the dev+ community, and maybe even the Devs themselves (though I doubt they will use it.)

    While I've been working on a personal project, I have been using a lot of prefabs. And, as in most projects that use a lot of prefabs, I was seeing a huge amount of repetition in how things were looking, i.e. it was the same house over and over again, to the point it was extremely boring.

    Well, while watching a DevBlog video for a different game on YouTube, I seen something they were doing and decided to give it a go myself. (You can find the video, and the effect I was after here.)

    So, I spent some, writing up a couple scripts that, at least for me, recreated what I had seen in the video. What I ended up with, worked pretty well, at least for what I am aiming for. So, I figured that I would share the scripts with you.

    The scripts can be used individually, or together. If you want to use them together, the RandomMaterial script, needs to be applied to the objects that are generated by RandomObject script.

    Any questions about how it works, just fire me a message.

    A quick disclaimer:

    I am not an amazing coder, so there is probably a good portion of these scripts that are not the most efficient. So, feel free to make any changes you want to the scripts.

    Regarding use/licencing, for simplicity, I am releasing both scripts under a CC-BY-NC licence.

    If you are interested in using it in a commercial project, just send me a message and we can talk.

    ------------------------------------------------
    Script 1:

    Randomized Material

    This script will randomize the material applied to the parent object, from a selection of materials that the user can define. The intent, is for this script to be used on objects that have a single common mesh, but multiple different materials that can be applied to it.

    The randomization is based on the correct location of the object, and the randomization can be change to be based on different transform vectors.


    RandomMaterial.cs

    Code:
    using UnityEngine;
    
    [ExecuteInEditMode]
    public class RandomMaterial : MonoBehaviour
    {
       
        public enum vectorEnum { X, Y, Z, XY, XZ, YZ };
        [Header("Generation")]
        [Tooltip("The transform plane the randomization is based on")]
        public vectorEnum randomizeationVector;
        [Tooltip("The possible materials to randomize between")]
        public Material[] Materials;
        [Header("Manual Control")]
        [Tooltip("Manually control the material")]
        public bool overrideMaterial = false;
        [Tooltip("Material index to use for manual override")]
        public int OverrideIndex = 0;
        [Header("Apply")]
        [Tooltip("This will apply all of the settings and delete the script")]
        public bool ApplyChanges = false;
    
        private float p = 0f;
        private Material targetMaterial;
        private Renderer rend;
    
    
        void OnStart()
        {
            if (Application.isPlaying) // fail safe incase he script is still applied at run time.
            {
                Destroy(this);
            }
        }
    
    
        public void Update (){
    
           
            if (Materials.Length >= 1 && Materials[Materials.Length-1] != null && !Application.isPlaying) // Stops the script from removing the default material until the array has been filled.
            {
                switch (randomizeationVector)
                {
                    case vectorEnum.X:
                        p = randomValueFromFloat(this.gameObject.transform.position.x);
                        break;
                    case vectorEnum.Y:
                        p = randomValueFromFloat(this.gameObject.transform.position.y);
                        break;
                    case vectorEnum.Z:
                        p = randomValueFromFloat(this.gameObject.transform.position.z);
                        break;
                    case vectorEnum.XY:
                        p = randomValueFromFloat(this.gameObject.transform.position.x * this.gameObject.transform.position.y);
                        break;
                    case vectorEnum.XZ:
                        p = randomValueFromFloat(this.gameObject.transform.position.x * this.gameObject.transform.position.y);
                        break;
                    case vectorEnum.YZ:
                        p = randomValueFromFloat(this.gameObject.transform.position.y * this.gameObject.transform.position.z);
                        break;
                }
    
                for (int x = 0; x < Materials.Length; x++)
                {
                    if (applyMaterial(p, Materials.Length, x))
                    {
                        targetMaterial = Materials[x];
                        break;
                    }
                }
               
               
                if (overrideMaterial)
                {
                    if (OverrideIndex >= Materials.Length)
                    {
                        OverrideIndex = Materials.Length - 1; // stops the index value going above the array limit.
                    }
                    targetMaterial = Materials[OverrideIndex];
                }
                rend = this.GetComponent<Renderer>();
                rend.material = targetMaterial;
    
                if (ApplyChanges)
                {
                    DestroyImmediate(this);
                }
            }
        }
    
        private float randomValueFromFloat(float seed)
        {
            Random.seed = (int)seed;
            return (Random.value);
    
        }
       
    
        private bool applyMaterial(float p, int length, int x)
        {
            if (p < (1f / length) + ((float)x / length)){return (true);}
            else { return (false); }
    
        }
    
    }
    
    
    

    ------------------------------------------

    Script 2:

    Randomized Objects

    This script will randomize the game object from a selection of game objects that the user can define. The intent, is for this script to be used on an empty game object, to prevent object overlap. The script will remove the empty game object when its applied.

    The randomization is based on the correct location of the object, and the randomization can be change to be based on different transform vectors.

    RandomObject.cs

    Code:
    using UnityEngine;
    
    
    [ExecuteInEditMode]
    public class RandomObject : MonoBehaviour
    {
        public enum vectorEnum { X, Y, Z, XY, XZ, YZ };
        [Header("Generation")]
        [Tooltip("The transform plane the randomization is based on")]
        public vectorEnum randomizeationVector;
        [Tooltip("The possible prefabs to randomize between")]
        public GameObject[] Objects; 
        [Header("Manual Control")]
        [Tooltip("Manually control the object")]
        public bool OverrideObject = false;    
        [Tooltip("Object index to use for manual override")]
        public int OverrideIndex = 0;
        [Header("Has Random Material")]
        [Tooltip("Calls the Randomize Material script if present on the objects.")]
        public bool UseRandomMaterial = false;
        [Header("Apply")]
        [Tooltip("This will apply all of the settings and delete the script")]
        public bool ApplyChanges = false;
    
        private GameObject objTaget = null;
        private GameObject targetObject = null;
        private GameObject currentprefab = null;
        private float p = 0f;
        private float f = 0.5f; // vector offset used to prevent a multiply by zero occurance. 
        private bool isPlay = false;
    
        void Update()
        {
            if (Application.isPlaying) // fail safe incase he script is still applied at run time.
            {
                isPlay = true;
                Destroy(this);
            }
    
            if (Objects.Length >= 1 && Objects[0] != null && !isPlay )  // this stop the script from removing the default object until the array has 1 object added.
            {          
                switch (randomizeationVector)
                {                
                    case vectorEnum.X:
                        p = randomValueFromFloat(this.gameObject.transform.position.x);
                        break;
                    case vectorEnum.Y:
                        p = randomValueFromFloat(this.gameObject.transform.position.y);
                        break;
                    case vectorEnum.Z:
                        p = randomValueFromFloat(this.gameObject.transform.position.z);
                        break;
                    case vectorEnum.XY:
                        p = randomValueFromFloat((this.gameObject.transform.position.x + f)*( this.gameObject.transform.position.y + f));
                        break;
                    case vectorEnum.XZ:
                        p = randomValueFromFloat((this.gameObject.transform.position.x + f) * (this.gameObject.transform.position.y + f));
                        break;
                    case vectorEnum.YZ:
                        p = randomValueFromFloat((this.gameObject.transform.position.y + f) * (this.gameObject.transform.position.z + f ));
                        break;
                }
    
                for (int x = 0; x < Objects.Length; x++)
                {
                    if (applyObject(p, Objects.Length, x))
                    {
                        targetObject = Objects[x];
                        break;
                    }
                }
    
                if (OverrideObject)
                {
                    if (OverrideIndex >= Objects.Length)
                    {
                        OverrideIndex = Objects.Length - 1; // stops the index value going above the array limit.
                    }
                    targetObject = Objects[OverrideIndex];
                }
                if (Application.isEditor) // this is used to handle duplication of the child object when using play in editor.
                {
                    foreach (Transform child in this.transform)
                    {
                        GameObject.DestroyImmediate(child.gameObject);
                    }
                }
                if (currentprefab != null)
                {
                    DestroyImmediate(currentprefab);
                }
                currentprefab = Instantiate(targetObject); // creates the random object 
                currentprefab.transform.position = this.transform.position; // sets the random objects position to match source
                currentprefab.transform.parent = this.transform; //  attachs the random object to the parent
                if (UseRandomMaterial)
                {
                    if (currentprefab.GetComponent<RandomMaterial>()) // checks to see if the current prefab has the Random Material script, if so updates that.
                    {
                        RandomMaterial childScript = currentprefab.GetComponent<RandomMaterial>() as RandomMaterial;
                        childScript.Update();
                    }                
                }
                if (ApplyChanges)
                {
                    currentprefab.transform.parent = null;
                    DestroyImmediate(this);
                }
            }
        }
    
        private float randomValueFromFloat(float seed)
        {
            Random.seed = (int)seed;
            return (Random.value);        
        }
       
    
        private bool applyObject(float p, int length, int x)
        {
            if (p < (1f / length) + ((float)x / length)){return (true);}
            else { return (false); }
        }
    
    }
    
    
    
    -----------------------------

    To use either of the scripts, create a new C# script in unity using the same name as I did here (RandomMaterial.cs/RandomObject.cs) and copy+paste the code into the file. Save the work, and then just add the scripts to an object.

    Hope these are useful to someone.

    -=Korvash=-
     
    Last edited: Jan 5, 2016
    ZeCarlos likes this.
Thread Status:
Not open for further replies.