Перейти к публикации
Поиск в
  • Дополнительно...
Искать результаты, содержащие...
Искать результаты в...
  • Нужна помощь?

    Создайте тему в соответствующем разделе
    Не нужно писать всё в чат!
  • Загляните на торговую площадку

    Там вы можете купить
    всё что касается игровых серверов
  • Не хотите бан?

    Пожалуйста, ознакомьтесь с нашими правилами
    Не нарушайте порядок!
  • Продаёте или покупаете?

    Пользуйтесь услугами гаранта
    Мы сделаем вашу сделку безопасной
  • 0
Akuma

Анимация самолёта

Привет, может кто знает как решить проблему с самиком
Вкратце, у меня есть скрипт, который спавнит самолёт в небе(модельку взял обычного разрушеного с130), он летит по указаным координатам и падает там скользя по земле, но есть проблема, которая меня сильно вымораживает, это то, как он перемещается, как будто фпс 20 у него, даже поставив минимальное значение обновления тика
Не обращайте внимания на его подскоки в небе и на то, что нос поднимается в земле


 

class Plane_Base
{
	protected EntityAI m_Plane;

	protected ref Timer m_MoveTimer;
	protected float     m_LastUpdateTime;

	protected vector m_StartPos;
	protected vector m_EndPos;
	protected vector m_TargetPos;
	protected vector m_DirNorm;
	protected vector m_ForwardDir;
	protected float  m_PathLenXZ;
	protected float  m_PathDoneXZ;

	protected float  m_UpdateInterval;
	protected float  m_DiveStartDist; 
	protected float  m_SpeedMS;
	protected float  m_AltitudeAGL;     
	protected float  m_RotationLerp;

	protected vector m_CurrentOrientation;

	
	protected bool   m_DiveMode;        
	protected bool   m_SlideMode;       
	protected bool   m_NoseRaiseArmed; 

	
	protected float  m_SlideSpeed;
	protected float  m_SlideFriction;
	protected float  m_SlideHeight;     
	protected float  m_SlideTrigger;    
	protected float  m_StopRadius;      

	
	protected float  m_PitchDownDeg;
	protected float  m_PitchRateDegPerSec; 
	protected float  m_TargetPitch;     

	
	protected string m_WreckClass;
	protected float  m_WreckYOffset;

	
	protected float  m_YawOffsetDeg;
	protected float  m_LastGoodYawDeg;

	void Plane_Base(PlaneEventManager mgr = null)
	{
		m_MoveTimer       = null;
		m_LastUpdateTime  = 0;

		m_PathLenXZ       = 0;
		m_PathDoneXZ      = 0;

		m_UpdateInterval  = 0.01;
		m_SpeedMS         = 55.0;
		m_DiveStartDist   = 900.0;
		m_AltitudeAGL     = 230.0;  
		m_RotationLerp    = 0.1;

		m_DiveMode        = false;
		m_NoseRaiseArmed  = false; 

		m_SlideMode       = false;
		m_SlideSpeed      = 0.0;
		m_SlideFriction   = 14.0;
		m_SlideHeight     = 5.0;   
		m_SlideTrigger    = 120.0;  
		m_StopRadius      = 0.5;

		m_PitchDownDeg       = 15.0;  
		m_PitchRateDegPerSec = 40.0;  
		m_TargetPitch        = 0.0;

		m_WreckClass      = "Crash_Wreck_C130J";
		m_WreckYOffset    = 0.20;

		m_YawOffsetDeg    = 180.0;   
		m_LastGoodYawDeg  = 0.0;
	}

	protected float ClampF(float v, float a, float b)
	{
		if (v < a) return a;
		if (v > b) return b;
		return v;
	}

	protected float YawFromDir(vector d)
	{
		return Math.Atan2(d[0], d[2]) * Math.RAD2DEG;
	}

	void SpawnAndFly(vector startPos, vector endPos, float speedMS = 60.0, float altitudeAGL = 200.0, string planeClass = "Crash_Wreck_C130J", string wreckClass = "Crash_Wreck_C130J")
	{
		m_DiveMode      = false;
		m_SlideMode     = false;
		m_NoseRaiseArmed = false;
		m_TargetPitch   = 0.0;

		m_WreckClass    = wreckClass;
		StartCommon(startPos, endPos, speedMS, altitudeAGL, planeClass);
	}

	void SpawnAndDive(vector startPos, vector targetPos, float speedMS = 60.0, float startAltitudeAGL = 200.0, float endAltitudeAGL = 0.30, float unused = 0.0, string planeClass = "Crash_Wreck_C130J", string wreckClass = "Crash_Wreck_C130J")
	{
		m_DiveMode      = true;
		m_SlideMode     = false;
		m_NoseRaiseArmed = false;
		m_TargetPitch   = 0.0;

		m_SlideHeight   = endAltitudeAGL; 
		m_WreckClass    = wreckClass;

		StartCommon(startPos, targetPos, speedMS, startAltitudeAGL, planeClass);
	}

	protected void StartCommon(vector startPos, vector endPos, float speedMS, float altitudeAGL, string planeClass)
	{
		if (!GetGame().IsServer()) return;

		m_SpeedMS      = speedMS;
		m_AltitudeAGL  = altitudeAGL;
		m_StartPos     = startPos;
		m_EndPos       = endPos;
		m_TargetPos    = endPos;

		vector diffXZ = endPos - startPos; diffXZ[1] = 0;
		float distanceXZ = Math.Sqrt(diffXZ[0]*diffXZ[0] + diffXZ[2]*diffXZ[2]);
		if (distanceXZ < 0.1) distanceXZ = 0.1;

		float invLen = 1.0 / distanceXZ;
		m_DirNorm     = diffXZ * invLen;
		m_ForwardDir  = m_DirNorm;
		m_PathLenXZ   = distanceXZ;
		m_PathDoneXZ  = 0.0;

		
		vector pos = startPos;
		float ground = GetGame().SurfaceY(pos[0], pos[2]);
		pos[1] = ground + m_AltitudeAGL;

		m_Plane = EntityAI.Cast(GetGame().CreateObject(planeClass, pos, false, true, true));
		if (!m_Plane) return;

		float yawStart = YawFromDir(m_ForwardDir) + m_YawOffsetDeg;
		m_LastGoodYawDeg = yawStart;

		
		m_CurrentOrientation = Vector(yawStart, m_PitchDownDeg, 0);
		m_Plane.SetOrientation(m_CurrentOrientation);

		if (!m_MoveTimer) m_MoveTimer = new Timer(CALL_CATEGORY_GAMEPLAY);
		m_LastUpdateTime = GetGame().GetTime();
		m_MoveTimer.Run(m_UpdateInterval, this, "TickMove", null, true);
	}

	protected void TickMove()
	{
		if (!GetGame().IsServer()) return;
		if (!m_Plane) { StopAndDelete(); return; }

		float tNow = GetGame().GetTime();
		float dt   = (tNow - m_LastUpdateTime) / 1000.0;
		if (dt <= 0) { dt = m_UpdateInterval; }
		m_LastUpdateTime = tNow;

		vector pos = m_Plane.GetPosition();

		if (!m_SlideMode)
		{
			vector stepXZ = m_DirNorm * (m_SpeedMS * dt);
			pos[0] = pos[0] + stepXZ[0];
			pos[2] = pos[2] + stepXZ[2];

			
			float remX = m_TargetPos[0] - pos[0];
			float remZ = m_TargetPos[2] - pos[2];
			float rem  = Math.Sqrt(remX*remX + remZ*remZ);

			
			float ground    = GetGame().SurfaceY(pos[0], pos[2]);
			float flightY   = ground + m_AltitudeAGL;   
			float slideY    = ground + m_SlideHeight;   м
			float tBlend    = 1.0;

			if (m_DiveStartDist < m_SlideTrigger + 1.0)
			{
				m_DiveStartDist = m_SlideTrigger + 50.0; 
			}
			if (rem <= m_DiveStartDist)
			{
				float denom = (m_DiveStartDist - m_SlideTrigger);
				if (denom < 1.0) { denom = 1.0; }
				tBlend = (rem - m_SlideTrigger) / denom; 
				if (tBlend < 0.0) tBlend = 0.0;
				if (tBlend > 1.0) tBlend = 1.0;
			}

			
			pos[1] = slideY + (flightY - slideY) * tBlend;

			m_Plane.SetPosition(pos);

			if (!m_NoseRaiseArmed && rem <= m_SlideTrigger)
        	{
            	m_NoseRaiseArmed = true;
        	}

			
			UpdateOrientation(stepXZ, dt);

			
			float stepLenXZ = Math.Sqrt(stepXZ[0]*stepXZ[0] + stepXZ[2]*stepXZ[2]);
			m_PathDoneXZ = m_PathDoneXZ + stepLenXZ;

			
			if (rem <= m_SlideTrigger || m_PathDoneXZ >= m_PathLenXZ)
			{
				
				float gyG = GetGame().SurfaceY(pos[0], pos[2]);
				pos[1] = gyG + m_SlideHeight;
				m_Plane.SetPosition(pos);

				
				m_SlideMode  = true;
				m_SlideSpeed = m_SpeedMS;

				
				vector toSlide = m_TargetPos - pos; toSlide[1] = 0;
				float d2 = toSlide[0]*toSlide[0] + toSlide[2]*toSlide[2];
				if (d2 < 0.0001) { d2 = 0.0001; }
				float inv = 1.0 / Math.Sqrt(d2);
				m_ForwardDir = toSlide * inv;

				float yawNow = YawFromDir(m_ForwardDir) + m_YawOffsetDeg;
				m_LastGoodYawDeg = yawNow;

				
			}
		}
		else
		{
			
			vector toT = m_TargetPos - pos; toT[1] = 0;
			float dist = Math.Sqrt(toT[0]*toT[0] + toT[2]*toT[2]);

			
			if (dist <= m_StopRadius || m_SlideSpeed <= 0.1)
			{
				float gyEnd = GetGame().SurfaceY(pos[0], pos[2]);
				pos[1] = gyEnd + m_SlideHeight;
				m_Plane.SetPosition(pos);

				
				vector finalDir = m_TargetPos - m_StartPos; finalDir[1] = 0;
				if (finalDir[0]*finalDir[0] + finalDir[2]*finalDir[2] > 0.0001)
				{
					float yawFin = YawFromDir(finalDir) + m_YawOffsetDeg;
					m_LastGoodYawDeg = yawFin;
					m_CurrentOrientation = Vector(yawFin, 0, 0);
					m_Plane.SetOrientation(m_CurrentOrientation);
				}

				SpawnWreckAndDelete(pos);
				return;
			}

			
			float invd = 1.0 / Math.Max(0.0001, dist);
			vector dirTo = toT * invd;

			float moveLen = m_SlideSpeed * dt;
			if (moveLen > dist) { moveLen = dist; }
			vector step = dirTo * moveLen;

			pos[0] = pos[0] + step[0];
			pos[2] = pos[2] + step[2];

			
			float gy = GetGame().SurfaceY(pos[0], pos[2]);
			pos[1] = gy + m_SlideHeight;

			m_Plane.SetPosition(pos);

			
			float yawDeg = YawFromDir(dirTo) + m_YawOffsetDeg;
			m_LastGoodYawDeg = yawDeg;
			m_CurrentOrientation = Vector(yawDeg, m_CurrentOrientation[1], 0);
			m_Plane.SetOrientation(m_CurrentOrientation);

			
			m_SlideSpeed = m_SlideSpeed - (m_SlideFriction * dt);
			if (m_SlideSpeed < 0.0) { m_SlideSpeed = 0.0; }

			
			UpdateOrientation(dirTo * m_SlideSpeed, dt);
		}
	}



	protected void UpdateOrientation(vector stepXZ, float dt)
	{
		float yaw   = m_CurrentOrientation[0];
		float pitch = m_CurrentOrientation[1];
		float roll  = m_CurrentOrientation[2];

	
		float yawDeg = YawFromDir(m_DirNorm) + m_YawOffsetDeg;
		yaw = yawDeg;
		m_LastGoodYawDeg = yawDeg;

		float desiredRaw;
		if (m_SlideMode)
		{
			desiredRaw = 0.0;
		}
		else
		{
			if (m_NoseRaiseArmed)
			{
				desiredRaw = 0.0;
			}
			else
			{
				desiredRaw = m_PitchDownDeg; 
			}
		}

		
		float diff    = desiredRaw - m_TargetPitch;
		float maxStep = m_PitchRateDegPerSec * dt;
		if (diff >  maxStep)
		{
			diff =  maxStep;
		}
		if (diff < -maxStep)
		{
			diff = -maxStep;
		}
		m_TargetPitch = m_TargetPitch + diff;

		
		float k = m_RotationLerp * dt * 25.0;
		if (k > 0.5)
		{
			k = 0.5;
		}
		pitch = Math.Lerp(pitch, m_TargetPitch, k);

		
		roll  = Math.Lerp(roll, 0.0, k);

		m_CurrentOrientation = Vector(yaw, pitch, roll);
		m_Plane.SetOrientation(m_CurrentOrientation);
	}



	protected void SpawnWreckAndDelete(vector atPos)
	{
		float gx = atPos[0];
    	float gz = atPos[2];

    	float gyTerrain = GetGame().SurfaceY(gx, gz);
		vector wreckPos = Vector(gx, gyTerrain + 5.0, gz);

		EntityAI wreck = EntityAI.Cast(GetGame().CreateObject(m_WreckClass, wreckPos, false, true, true));
		if (wreck)
		{
			vector o = Vector(m_LastGoodYawDeg, 0, 0);
			wreck.SetOrientation(o);
		}

		StopAndDelete();
	}

	void StopAndDelete()
	{
		if (m_MoveTimer) m_MoveTimer.Stop();
		if (m_Plane)
		{
			GetGame().ObjectDelete(m_Plane);
			m_Plane = null;
		}
	}
}


 

 

Изменено пользователем Akuma (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Рекомендованные сообщения

  • 0

Проблема заключается в том, что ты вызываешь установку позиций с серверной части. Грамотным решением реализации будет отправка rpc на клиент, уведомляя клиента о том, что самолёт вылетел, а далее спавнить локальный самолёт и менять ему уже позицию на клиентской части.

Изменено пользователем Stein35 (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
MagicByte MagicByte MagicByte

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

×
×
  • Создать...

Важная информация

Используя этот сайт, вы автоматически обязуетесь соблюдать наши Правила и Политика конфиденциальности.
Чтобы сделать этот веб-сайт лучше, мы разместили cookies на вашем устройстве. Вы можете изменить свои настройки cookies, в противном случае мы будем считать, что вы согласны с этим.

Поддержка