first commit

This commit is contained in:
2026-06-04 21:37:43 +03:00
commit a6ea987b0d
152 changed files with 34059 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
using OTG.Lab06.Abilities;
using UnityEngine;
namespace OTG.Lab06.Effects
{
public sealed class BlinkEffect : AbilityEffect
{
[SerializeField] private float obstaclePadding = 0.8f;
[SerializeField] private LayerMask obstacleMask = ~0;
[SerializeField] private float visualLifetime = 0.8f;
public override void Activate(AbilityCastContext context)
{
Vector3 start = context.Caster.position;
Vector3 direction = context.Forward;
float distance = Mathf.Max(0.1f, context.Ability.castRange);
Vector3 target = start + direction * distance;
CharacterController controller = context.Caster.GetComponent<CharacterController>();
if (controller != null)
{
controller.enabled = false;
}
if (Physics.SphereCast(start + Vector3.up, 0.45f, direction, out RaycastHit hit, distance, obstacleMask, QueryTriggerInteraction.Ignore))
{
target = hit.point - direction * obstaclePadding;
target.y = start.y;
}
context.Caster.position = target;
if (controller != null)
{
controller.enabled = true;
}
transform.position = target + Vector3.up * 0.05f;
Destroy(gameObject, visualLifetime);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ea451cce3e2635fa0b12e607a4978a19
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+83
View File
@@ -0,0 +1,83 @@
using OTG.Lab06.Abilities;
using OTG.Lab06.Core;
using UnityEngine;
namespace OTG.Lab06.Effects
{
[RequireComponent(typeof(Collider))]
public sealed class FireballEffect : AbilityEffect
{
[SerializeField] private float speed = 18f;
[SerializeField] private float lifeTime = 4f;
[SerializeField] private LayerMask hitMask = ~0;
private AbilityCastContext context;
private Vector3 direction;
private float remainingLife;
private bool activated;
public override void Activate(AbilityCastContext context)
{
this.context = context;
direction = context.Forward;
remainingLife = Mathf.Min(lifeTime, Mathf.Max(0.5f, context.Ability.castRange / Mathf.Max(1f, speed)));
activated = true;
transform.position = context.Origin + direction * 0.9f;
transform.rotation = Quaternion.LookRotation(direction, Vector3.up);
}
private void Awake()
{
Collider ownCollider = GetComponent<Collider>();
ownCollider.isTrigger = true;
}
private void Update()
{
if (!activated)
{
return;
}
float step = speed * Time.deltaTime;
if (Physics.Raycast(transform.position, direction, out RaycastHit hit, step, hitMask, QueryTriggerInteraction.Ignore))
{
ApplyHit(hit.collider);
return;
}
transform.position += direction * step;
remainingLife -= Time.deltaTime;
if (remainingLife <= 0f)
{
Destroy(gameObject);
}
}
private void OnTriggerEnter(Collider other)
{
if (!activated || other.transform == context.Caster)
{
return;
}
ApplyHit(other);
}
private void ApplyHit(Collider hitCollider)
{
if (hitCollider.transform == context.Caster || hitCollider.GetComponentInParent<AbilityEffect>() != null)
{
return;
}
IDamageable damageable = hitCollider.GetComponentInParent<IDamageable>();
if (damageable != null && damageable.IsAlive)
{
damageable.TakeDamage(context.Ability.damage);
}
Destroy(gameObject);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5fb2a27798b1a5343b1d83247d298809
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+33
View File
@@ -0,0 +1,33 @@
using System.Collections.Generic;
using OTG.Lab06.Abilities;
using OTG.Lab06.Core;
using UnityEngine;
namespace OTG.Lab06.Effects
{
public sealed class IceNovaEffect : AbilityEffect
{
[SerializeField] private float visualLifetime = 1.2f;
[SerializeField] private LayerMask hitMask = ~0;
public override void Activate(AbilityCastContext context)
{
transform.position = context.Caster.position + Vector3.up * 0.05f;
float radius = Mathf.Max(0.1f, context.Ability.castRange);
Collider[] hits = Physics.OverlapSphere(context.Caster.position, radius, hitMask, QueryTriggerInteraction.Ignore);
var damaged = new HashSet<IDamageable>();
foreach (Collider hit in hits)
{
IDamageable damageable = hit.GetComponentInParent<IDamageable>();
if (damageable != null && damageable.IsAlive && damageable.Transform != context.Caster && damaged.Add(damageable))
{
damageable.TakeDamage(context.Ability.damage);
}
}
Destroy(gameObject, visualLifetime);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0b67bd6b1b5bec522bf4df1a07f67357
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+14
View File
@@ -0,0 +1,14 @@
using UnityEngine;
namespace OTG.Lab06.Effects
{
public sealed class SelfDestruct : MonoBehaviour
{
[SerializeField] private float lifetime = 1f;
private void Start()
{
Destroy(gameObject, lifetime);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 099f4381a14a70847b2fcc301915e4dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: