123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- using UnityEngine;
- using System.Collections;
- [RequireComponent(typeof(LineRenderer))]
- public class F3DBeam : MonoBehaviour
- {
- public LayerMask layerMask;
- public F3DFXType fxType; // Weapon type
- public bool OneShot; // Constant or single beam?
-
- public Texture[] BeamFrames; // Animation frame sequence
- public float FrameStep; // Animation time
- public float beamScale; // Default beam scale to be kept over distance
- public float MaxBeamLength; // Maximum beam length
- public bool AnimateUV; // UV Animation
- public float UVTime; // UV Animation speed
-
- public Transform rayImpact; // Impact transform
- public Transform rayMuzzle; // Muzzle flash transform
- LineRenderer lineRenderer; // Line rendered component
- RaycastHit hitPoint; // Raycast structure
- int frameNo; // Frame counter
- int FrameTimerID; // Frame timer reference
- float beamLength; // Current beam length
- float initialBeamOffset; // Initial UV offset
- void Awake()
- {
- // Get line renderer component
- lineRenderer = GetComponent<LineRenderer>();
- // Assign first frame texture
- if (!AnimateUV && BeamFrames.Length > 0)
- lineRenderer.material.mainTexture = BeamFrames[0];
- // Randomize uv offset
- initialBeamOffset = Random.Range(0f, 5f);
- }
-
- // OnSpawned called by pool manager
- void OnSpawned()
- {
- // Do one time raycast in case of one shot flag
- if (OneShot)
- Raycast();
- // Start animation sequence if beam frames array has more than 2 elements
- if (BeamFrames.Length > 1)
- Animate();
- // Play audio depending on weapon type
- switch (fxType)
- {
- case F3DFXType.PlasmaBeam:
- // Spawn audio source prefab at specified position linked to parent of current transform
- F3DAudioController.instance.PlasmaBeamLoop(transform.position, transform.parent);
- break;
- case F3DFXType.PlasmaBeamHeavy:
- F3DAudioController.instance.PlasmaBeamHeavyLoop(transform.position, transform.parent);
- break;
- default:
- break;
- }
- }
- // OnDespawned called by pool manager
- void OnDespawned()
- {
- // Reset frame counter
- frameNo = 0;
- // Clear timer
- if (FrameTimerID != -1)
- {
- F3DTime.time.RemoveTimer(FrameTimerID);
- FrameTimerID = -1;
- }
-
- // Play audio
- switch (fxType)
- {
- case F3DFXType.PlasmaBeam:
- F3DAudioController.instance.PlasmaBeamClose(transform.position);
- break;
- case F3DFXType.PlasmaBeamHeavy:
- F3DAudioController.instance.PlasmaBeamHeavyClose(transform.position);
- break;
- default:
- break;
- }
- }
- // Hit point calculation
- void Raycast()
- {
- // Prepare structure and create ray
- hitPoint = new RaycastHit();
- Ray ray = new Ray(transform.position, transform.forward);
- // Calculate default beam proportion multiplier based on default scale and maximum length
- float propMult = MaxBeamLength * (beamScale / 10f);
- // Raycast
- if (Physics.Raycast(ray, out hitPoint, MaxBeamLength, layerMask))
- {
- // Get current beam length and update line renderer accordingly
- beamLength = Vector3.Distance(transform.position, hitPoint.point);
- lineRenderer.SetPosition(1, new Vector3(0f, 0f, beamLength));
- // Calculate default beam proportion multiplier based on default scale and current length
- propMult = beamLength * (beamScale / 10f);
- // Spawn prefabs and apply force
- switch (fxType)
- {
- case F3DFXType.Sniper:
-
- F3DFXController.instance.SniperImpact(hitPoint.point + hitPoint.normal * 0.2f);
- ApplyForce(4f);
- break;
-
- case F3DFXType.RailGun:
- F3DFXController.instance.RailgunImpact(hitPoint.point + hitPoint.normal * 0.2f);
- ApplyForce(7f);
- break;
-
- case F3DFXType.PlasmaBeam:
- ApplyForce(0.5f);
- break;
-
- case F3DFXType.PlasmaBeamHeavy:
- ApplyForce(2f);
- break;
- default:
- break;
- }
- // Adjust impact effect position
- if (rayImpact)
- rayImpact.position = hitPoint.point - transform.forward * 0.5f;
- }
- // Nothing was his
- else
- {
- // Set beam to maximum length
- beamLength = MaxBeamLength;
- lineRenderer.SetPosition(1, new Vector3(0f, 0f, beamLength));
- // Adjust impact effect position
- if (rayImpact)
- rayImpact.position = transform.position + transform.forward * beamLength;
- }
- // Adjust muzzle position
- if(rayMuzzle)
- rayMuzzle.position = transform.position + transform.forward * 0.1f;
- // Set beam scaling according to its length
- lineRenderer.material.SetTextureScale("_MainTex", new Vector2(propMult, 1f));
- }
- // Advance texture frame
- void OnFrameStep()
- {
- // Set current texture frame based on frame counter
- lineRenderer.material.mainTexture = BeamFrames[frameNo];
- frameNo++;
- // Reset frame counter
- if (frameNo == BeamFrames.Length)
- frameNo = 0;
- }
- // Initialize frame animation
- void Animate()
- {
- if (BeamFrames.Length > 1)
- {
- // Set current frame
- frameNo = 0;
- lineRenderer.material.mainTexture = BeamFrames[frameNo];
- // Add timer
- FrameTimerID = F3DTime.time.AddTimer(FrameStep, BeamFrames.Length - 1, OnFrameStep);
- frameNo = 1;
- }
- }
- // Apply force to last hit object
- void ApplyForce(float force)
- {
- if (hitPoint.rigidbody != null)
- hitPoint.rigidbody.AddForceAtPosition(transform.forward * force, hitPoint.point, ForceMode.VelocityChange);
- }
-
- void Update()
- {
- // Animate texture UV
- if (AnimateUV)
- lineRenderer.material.SetTextureOffset("_MainTex", new Vector2(Time.time * UVTime + initialBeamOffset, 0f));
- // Raycast for laser beams
- if (!OneShot)
- Raycast();
- }
- }
|