| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- using MathNet.Numerics;
- using o0.Wave.RealTime.Old;
- using ShatterToolkit;
- using ShatterToolkit.Helpers;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public enum FruitType
- {
- Normal,
- Bomb,
- FrozenBanana,
- ComboPomegranate,
- RainbowApple
- }
- public class FruitBehavior : MonoBehaviour
- {
- public const float ArrivingDist = 5.0f;
- [SerializeField] public Material IceMat_NoTex = null;
- [SerializeField] public Material IceMat_Tex = null;
- private List<List<Material>> MatBeforeFrost = new List<List<Material>>();
-
- private float Trajectory_coef_a; // y = ax^2 + bx + c
- private float Trajectory_coef_b; // y = ax^2 + bx + c
- private float Trajectory_coef_c; // y = ax^2 + bx + c
- private Vector3 Original_position;
- private Vector3 Target_position;
- private float ExistingTime = 0f;
- private float TrajectoryTime = 0f;
- private float TrajectoryLifetime = 0f;
- public bool bMoveAlongTrajectory = true;
- private Vector3 SpinAxis;
- private float SpinSpeed;
- private FruitType Type;
- private GamingManager _gamingManager;
- private Material PostSplitMat;
- private GameObject JuiceSplash;
- public Sprite JuiceStain;
- public delegate void ArriveDelegate(FruitBehavior fb);
- public delegate void OnHitDelegete(FruitBehavior fb, Vector3 hit_p, bool bCritical);
- public event ArriveDelegate OnArrive;
- public event OnHitDelegete OnHitEvent;
- private GameObject MeshParent;
- public FruitType GetFruitType()
- {
- return Type;
- }
- // Which meshes should be shattered
- private List<GameObject> ToShatter = new List<GameObject>();
- void Awake()
- {
- }
- private void Start()
- {
- }
- // Update is called once per frame
- void Update()
- {
- if (!_gamingManager.IsGamePaused())
- {
- ExistingTime += Time.deltaTime;
- if (transform.position.z < ArrivingDist)
- {
- OnArrive.Invoke(this);
- }
- if (Type == FruitType.ComboPomegranate || Type == FruitType.RainbowApple || Type == FruitType.FrozenBanana)
- {
- MeshRenderer[] renderers = GetComponentsInChildren<MeshRenderer>();
- foreach (var renderer in renderers)
- {
- Material[] mats = renderer.materials;
- foreach (var mat in mats)
- {
- float sin_x = ExistingTime * Mathf.PI * 2f;
- float sin_y = Mathf.Sin(sin_x);
- float value = (sin_y + 1f) * 0.5f * 0.65f;
- Color flicker = new Color(value, value, value);
- mat.SetColor("_EmissionColor", flicker);
- }
- }
-
- }
- }
- // Moves along trajectory, if not in combo pomegranate time
- if (bMoveAlongTrajectory)
- {
- TrajectoryTime += Time.deltaTime;
- float parabola_x = Mathf.Lerp(Original_position.z, Target_position.z, TrajectoryTime / TrajectoryLifetime);
- float parabola_y = Trajectory_coef_a * parabola_x * parabola_x + Trajectory_coef_b * parabola_x + Trajectory_coef_c;
- float pos_x = Mathf.Lerp(Original_position.x, Target_position.x, TrajectoryTime / TrajectoryLifetime);
- gameObject.transform.position = new Vector3(pos_x, parabola_y, parabola_x);
- // Random spinning
- transform.Rotate(SpinAxis, Time.deltaTime * SpinSpeed);
- }
- }
- //枪设备下设置碰撞层和tag
- string tagToSet = "Fruit";
- string layerToSet = "Target1";
- public void Init(FruitType ty, GamingManager manager, Vector3 spawnLocation, Vector3 targetLocation, float timeToArraive)
- {
- _gamingManager = manager;
- Type = ty;
- Original_position = spawnLocation;
- Target_position = targetLocation;
- GamingValues.CalcTrajectoryEquationCoef(spawnLocation, targetLocation, out Trajectory_coef_a, out Trajectory_coef_b, out Trajectory_coef_c);
- TrajectoryLifetime = timeToArraive;
- GameObject fruit = _gamingManager.gameObject.GetComponent<FruitTypeList>().GetFruit(ty, true, out PostSplitMat, out JuiceSplash, out JuiceStain);
- MeshParent = Instantiate(fruit, gameObject.transform);
- //SphereCollider sphr_collider = meshParent.GetComponent<SphereCollider>();
- //if (sphr_collider)
- //{
- // SphereCollider _collider = gameObject.AddComponent<SphereCollider>();
- // _collider.isTrigger = true;
- // _collider.radius = sphr_collider.radius;
- //}
- if (GlobalData.MyDeviceMode == DeviceMode.Gun) {
- gameObject.tag = tagToSet;
- gameObject.layer = LayerMask.NameToLayer(layerToSet);
- MeshParent.tag = tagToSet;
- MeshParent.layer = LayerMask.NameToLayer(layerToSet);
- }
-
- Rigidbody _body = gameObject.AddComponent<Rigidbody>();
- _body.isKinematic = true;
- _body.useGravity = false;
- //Destroy(GetComponent<Collider>());
- // Find out which meshes will participate in shattering
- for (int i = 0; i < MeshParent.transform.childCount; i++)
- {
- GameObject go = MeshParent.transform.GetChild(i).gameObject;
- if (go.CompareTag("ShatterIncluded"))
- {
- if (GlobalData.MyDeviceMode == DeviceMode.Gun) {
- go.tag = tagToSet;
- go.layer = LayerMask.NameToLayer(layerToSet);
- }
- ShatterTool st = go.AddComponent<ShatterTool>();
- PieceRemover pr = go.AddComponent<PieceRemover>();
- st.GenerationLimit = 2;
- pr.startAtGeneration = 2;
- pr.timeDelay = 1f;
- st.SendPostSplitMessage = true;
- go.AddComponent<TargetUvMapper>();
- ToShatter.Add(go);
- }
- // Backup the origin mats of the fruit, used to recover from forst
- MeshRenderer renderer = go.GetComponent<MeshRenderer>();
- MatBeforeFrost.Add(new List<Material>());
- foreach (var mat in renderer.materials)
- {
- MatBeforeFrost[i].Add(mat);
- }
-
- }
- // If this is a ComboPomegarante, add a specialized behavior component
- if (Type == FruitType.ComboPomegranate)
- {
- gameObject.AddComponent<ComboPomegaranteBehavior>().Init(_gamingManager);
- }
- // Get a random rotation axis and speed
- SpinAxis = Random.rotation * Vector3.forward;
- SpinSpeed = Random.Range(90f, 180f);
- }
- private void OnTriggerEnter(Collider other)
- {
- //水果爆炸不拦截
- // If is hit by a fullscreen clearing bubble
- FullscreenClearBubbleBehavior bubble = other.gameObject.GetComponent<FullscreenClearBubbleBehavior>();
- if (bubble)
- {
- OnHitEvent.Invoke(this, gameObject.transform.position, false);
- return;
- }
- //拦截子弹碰撞
- if (GlobalData.MyDeviceMode == DeviceMode.Gun) return;
- // If is hit by an arrow
- ArrowBehavior arrow = other.gameObject.GetComponent<ArrowBehavior>();
- if (arrow)
- {
- arrow.HitAFruit();
- float fruit_dist = gameObject.transform.position.magnitude;
- Vector3 point_along_arrow_dir = (arrow.transform.position.normalized * fruit_dist);
- if ((point_along_arrow_dir - gameObject.transform.position).magnitude <= 1f)
- {
- OnHitEvent.Invoke(this, other.ClosestPoint(gameObject.transform.position), true);
- }
- else
- {
- OnHitEvent.Invoke(this, other.ClosestPoint(gameObject.transform.position), false);
- }
- return;
- }
- }
- public void OnHitCollision(Collider other, ArrowBehavior shootObj)
- {
- // If is hit by an arrow
- if (shootObj)
- {
- shootObj.HitAFruit();
- float fruit_dist = gameObject.transform.position.magnitude;
- Vector3 point_along_arrow_dir = (shootObj.transform.position.normalized * fruit_dist);
- if ((point_along_arrow_dir - gameObject.transform.position).magnitude <= 1f)
- {
- OnHitEvent.Invoke(this, other.ClosestPoint(gameObject.transform.position), true);
- }
- else
- {
- OnHitEvent.Invoke(this, other.ClosestPoint(gameObject.transform.position), false);
- }
- return;
- }
- // If is hit by a fullscreen clearing bubble
- FullscreenClearBubbleBehavior bubble = other.gameObject.GetComponent<FullscreenClearBubbleBehavior>();
- if (bubble)
- {
- OnHitEvent.Invoke(this, gameObject.transform.position, false);
- return;
- }
- }
- // Play smashing effect, including shattering the mesh and instantiate an smashing audio which will be delay-destroyed
- public void SmashEffect()
- {
- foreach (var go in ToShatter)
- {
- Rigidbody rb = go.AddComponent<Rigidbody>();
- rb.mass = 1.0f; // add rigidbody right before shatter this mesh, then it will be destroyed along with the gameobject
- rb.angularDrag = 5f;
- PostSplitBehaviour psb = go.AddComponent<PostSplitBehaviour>();
- psb.PostSplitMat = PostSplitMat;
- psb.ExplosionPosition = gameObject.transform.position;
- go.SendMessage("Shatter", gameObject.transform.position);
- }
- GameObject fruitJuice = Instantiate(JuiceSplash, gameObject.transform.position, Quaternion.identity);
- AudioSource audio = fruitJuice.AddComponent<AudioSource>();
- audio.clip = _gamingManager.GetAudioManager().GetRandomSound((Type == FruitType.Bomb) ? SoundCategory.BombExplode : SoundCategory.FruitSmash);
- if (UserSettings.ins.openEffect) audio.Play();
- GamingManager.DelayDestroy(_gamingManager, fruitJuice, (Type == FruitType.Bomb) ? 3f : 1.5f);
- Destroy(gameObject);
- }
- public void Frost()
- {
- Debug.Log("Start Frost");
- for (int i = 0; i < MeshParent.transform.childCount; i++)
- {
- GameObject go = MeshParent.transform.GetChild(i).gameObject;
- MeshRenderer renderer = go.GetComponent<MeshRenderer>();
- Material[] iced_mats = new Material[renderer.materials.Length];
- for (int j = 0; j < renderer.materials.Length; j++)
- {
- Color originColor = renderer.materials[j].color;
- if (renderer.materials[j].mainTexture == null)
- {
- iced_mats[j] = new Material(IceMat_Tex);
- }
- else
- {
- iced_mats[j] = new Material(IceMat_NoTex);
- iced_mats[j].SetColor("_MainCol", originColor);
- }
- }
- renderer.materials = iced_mats;
- }
- }
- public void UnFrost()
- {
- for (int i = 0; i < MeshParent.transform.childCount; i++)
- {
- GameObject go = MeshParent.transform.GetChild(i).gameObject;
- MeshRenderer renderer = go.GetComponent<MeshRenderer>();
- Material[] new_mats = new Material[renderer.materials.Length];
- for (int j = 0; j < renderer.materials.Length; j++)
- {
- new_mats[j] = MatBeforeFrost[i][j];
- }
- renderer.materials = new_mats;
- }
- }
- }
|