public void Initialize(Vector3 position, Vector3 normal, Vector3 velocity, [NotNull] Transform parent) { var size = _splatters.Core.DecalSize; if (_splatters.RandomizeSize.Enabled) { size *= Random.Range(_splatters.RandomizeSize.MinInflation, _splatters.RandomizeSize.MaxInflation); } var rotationAngle = Mathf.Acos(Vector3.Dot(Vector3.up, normal)) * Mathf.Rad2Deg; var rotationAxis = Vector3.Cross(Vector3.up, normal).normalized; var orientation = Quaternion.AngleAxis(rotationAngle, rotationAxis); position += normal * _splatters.Core.VerticalOffset; // Modify the transform according to the particle impact velocity if (_splatters.ImpactVelocity.Enabled) { // Project impact velocity onto plane defined by collision normal var velocityOnPlane = velocity - Vector3.Dot(velocity, normal) * normal; var speedOnPlane = velocityOnPlane.magnitude; var dirOnPlane = velocityOnPlane / speedOnPlane; // Align with impact velocity (randomised orientation should be equally spread around this axis) var impactOrientation = Quaternion.LookRotation(dirOnPlane, Vector3.up); orientation *= impactOrientation; // Stretch along impact direction according to impact speed var stretch = _splatters.ImpactVelocity.Scale.Evaluate(speedOnPlane); size.z *= stretch; // Offset position according to impact speed and length var offset = _splatters.ImpactVelocity.Offset.Evaluate(speedOnPlane); position += dirOnPlane * offset * size.z; } // Randomize the orientation. Rotating a max of half the range ccw, and half the range cw (i.e. distributing the rotation around the current facing direction) if (_splatters.RandomizeOrientation.Enabled) { orientation *= Quaternion.AngleAxis((Random.value - 0.5f) * _splatters.RandomizeOrientation.RandomDegrees, Vector3.up); } var worldTransform = Matrix4x4.TRS(position, orientation, size); _parent = parent; _localTransform = parent.worldToLocalMatrix * worldTransform; _totalLifetime = _splatters.Lifetime.Enabled ? Random.Range(_splatters.Lifetime.MinLifetime, _splatters.Lifetime.MaxLifetime) : 1; _remainingLifetime = _totalLifetime; AgeingRate = 1; _render = _splatters._decalSystem.Add(this); }
protected virtual void OnEnable() { Log.Trace("OnEnable"); _settings.Init(); _settings.Changed += OnSettingsChanged; if (_system == null) { _system = new WetDecalSystem(); } _render = _system.Add(this); RequireUpdate(UpdateType.Rebuild, true); }