public void ProjectileIntercepted(Projectile pr, RaycastHit2D hit) { // Called on both client and server. // Disable the projectile. // On server, this is authorative. // On client, this hides it, and could lead to visual desync. Oh well. // Ignore if not attached. if (!Attachment.IsAttached) { return; } // Do not shoot down our own projectiles! if (Attachment.ParentUnit.Faction == pr.Faction) { return; } pr.Disable(hit.point); // Play the shoot down effect, and spawn a shot down particle effect. PlayShootdownAnim(hit.point); var particle = Pool.Get(TempEffect.GetPrefab(TempEffects.DESTROYED_SPARKS).PoolableObject); particle.transform.position = hit.point; particle.transform.eulerAngles = pr.transform.eulerAngles; }
private void UnloadStaticAssets() { if (!LoadedStatic) { // Projectiles... ProjectileData.Unload(); TempEffect.UnloadAll(); Attachment.Unload(); // Resources cleanup... Resources.UnloadUnusedAssets(); LoadedStatic = false; } }
private void UnloadStaticAssets() { if (!LoadedStatic) { // Projectiles... ProjectileData.UnloadAll(); TempEffect.UnloadAll(); Item.UnloadAll(); MeshGen.ClearCache(); TileData.UnloadAll(); // Resources cleanup... Resources.UnloadUnusedAssets(); LoadedStatic = false; } }
private IEnumerator LoadStaticAssets() { if (!LoadedStatic) { LoadedStatic = false; List <KeyValuePair <string, Run> > actions = new List <KeyValuePair <string, Run> >(); actions.Add(new KeyValuePair <string, Run>("Loading Items...", () => { Item.LoadAll(); })); actions.Add(new KeyValuePair <string, Run>("Loading Projectiles...", () => { ProjectileData.LoadAll(); })); actions.Add(new KeyValuePair <string, Run>("Loading Effects...", () => { TempEffect.LoadAll(); })); actions.Add(new KeyValuePair <string, Run>("Loading Tiles...", () => { TileData.LoadAll(); })); actions.Add(new KeyValuePair <string, Run>("Registering Items...", () => { Item.NetRegisterAll(); })); int total = actions.Count; System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); // Loop and execute... for (int i = 0; i < total; i++) { var pair = actions[i]; // Execute... UI.Title = pair.Key; UI.Percentage = i / total; yield return(null); watch.Restart(); try { pair.Value.Invoke(); } catch (Exception e) { Debug.LogError("Exception when loading on step #{0} - '{1}':\n{2}".Form(i, pair.Key, e)); } watch.Stop(); Debug.Log("'{0}' - Took {1} milliseconds.".Form(pair.Key, watch.ElapsedMilliseconds)); } LoadedStatic = true; StartCoroutine(LoadScene()); } }
private void UnloadStaticAssets() { if (!LoadedStatic) { // Unload all here. Item.UnloadAll(); Projectile.UnloadAll(); TempEffect.UnloadAll(); Level.UnloadAll(); // Resources cleanup... Resources.UnloadUnusedAssets(); // Do some GC. System.GC.Collect(); LoadedStatic = false; } }
public void ProcessHit(RaycastHit2D hit, int penetration, DamageModel model) { // Can run on either server or client. // On server, deals damage, applies forces. if (isServer) { ProcessServerHit(hit, penetration, model); } // On clients, spawns hit effects and audio ect. // TODO apply hit effect and audio. // Apply hit effect. if (model != null) { if (model.ColliderPartMap.ContainsKey(hit.collider)) { var hitEffect = model.ColliderPartMap[hit.collider].HitEffect; if (hitEffect != TempEffects.NONE) { // Spawn hit effect. var prefab = TempEffect.GetPrefab(hitEffect).PoolableObject; var effect = Pool.Get(prefab); if (effect != null) { effect.transform.position = hit.point; float angle = Mathf.Atan2(hit.normal.y, hit.normal.x) * Mathf.Rad2Deg; effect.transform.eulerAngles = new Vector3(0f, 0f, angle); } else { Debug.LogWarning("Tried to spawn effect for projectile hit, but the pool returned null!"); } } } } }
private void AddEffect(TempEffectType type, float duration, Vector3 pos, Vector3 dest, GameObject gameObject) { TempEffect te = new TempEffect(type, gameObject, duration, pos, dest); tempEffectList.Add(te); }
public void RpcSpawnTempEffect(byte effect, Vector2 position, float angle) { TempEffects e = (TempEffects)effect; TempEffect.NetCallback(e, position, angle); }
public void ResolveCollisions(Vector2 currentPos, Vector2 predictedPos, float currentAngle, out Vector2 finalPos, out float finalAngle) { // Detect and solve collisions between current and future pos. Physics2D.queriesStartInColliders = false; int totalHits = Physics2D.LinecastNonAlloc(currentPos, predictedPos, hits, CollisionMask); if (totalHits > MAX_RAY_HITS) { Debug.LogWarning("Number of ray hits exceeded the processing capacity! Capacity is {0}, hit {1} colliders. Consider upping the MAX_RAY_HITS value in Projectile.cs.".Form(MAX_RAY_HITS, totalHits)); totalHits = MAX_RAY_HITS; } for (int i = 0; i < totalHits; i++) { var hit = hits[i]; // If it is a trigger, ignore. if (hit.collider.isTrigger) { continue; } // We hit something! ServerHit(hit); // For now, assume nothing can be penetrated through... // Check of we can bounce of this... if (bounceCount < Data.MaxBounces) { bounceCount++; Vector2 n = hit.normal; Vector2 b = Bearing; Vector2 newBearing = b - (2 * (Vector2.Dot(b, n)) * n); float angle = newBearing.ToAngle(); bool pos = Random.value >= 0.5f; float add = Random.Range(Mathf.Abs(Data.BounceAngleChange.x), Mathf.Abs(Data.BounceAngleChange.y)); angle += add * (pos ? 1f : -1f); finalAngle = angle; finalPos = hit.point; // Spawn a hit effect if (isServer) { TempEffect.NetSpawn(TempEffects.HIT_SPARKS_SMALL, hit.point + hit.normal * 0.15f, hit.normal.ToAngle()); } return; } // Just stop as soon as we hit something: destroy this object if on server. StopAll(); // Spawn a hit effect. // Spawn a hit effect, on the server so it is authorative: if a client sees a hit effect, it is 'real'. if (isServer) { TempEffect.NetSpawn(TempEffects.HIT_SPARKS, hit.point + hit.normal * 0.15f, hit.normal.ToAngle()); } // Break out of the method. finalPos = hit.point; finalAngle = currentAngle; return; } // Looks like no final collisions. finalPos = predictedPos; finalAngle = currentAngle; }
private void SpawnMuzzleFlash() { TempEffect.Spawn(EffectPrefab.MUZZLE_FLASH, Muzzle.transform.position, Muzzle.transform.eulerAngles.z + (Muzzle.lossyScale.x < 0f ? 180 : 0)); }