protected override void OnUpdate() { vertices.Clear(); // 頂点配列を初期化 indices.Clear(); // インデックス配列を初期化 var bufferArray = componentGroup.GetBufferArray <TrailBufferElement>(); for (var i = 0; i < componentGroup.CalculateLength(); ++i) { var buffer = bufferArray[i]; if (buffer.Length < 2) { continue; // 頂点が2個以下なら、線を作れないためスキップ } for (var j = 0; j < buffer.Length; ++j) { // 頂点をつなげて線を作っていく if (j > 0) { indices.Add(vertices.Count - 1); indices.Add(vertices.Count); } vertices.Add(buffer[j].Value); } } // Meshの更新 mesh.Clear(); mesh.SetVertices(vertices); mesh.SetIndices(indices.ToArray(), MeshTopology.Lines, 0); Graphics.DrawMesh(mesh, Matrix4x4.identity, Material, 0); // Meshの描画 }
protected override void OnUpdate() { transformGroup.SetFilter(TransformInternal.ComponentAuthority.NotAuthoritative); var transformToSetArray = transformGroup.GetComponentDataArray <TransformToSet>(); var transformBufferArray = transformGroup.GetBufferArray <BufferedTransform>(); for (int i = 0; i < transformToSetArray.Length; ++i) { var buffer = transformBufferArray[i]; if (buffer.Length == 0) { continue; } var bufferHead = buffer[0]; var currentTransform = new TransformToSet { Position = bufferHead.Position + worker.Origin, Orientation = bufferHead.Orientation, Velocity = bufferHead.Velocity, ApproximateRemoteTick = bufferHead.PhysicsTick }; transformToSetArray[i] = currentTransform; buffer.RemoveAt(0); } }
private void UpdateRigidbodyData() { transformGroup.SetFilter(TransformInternal.ComponentAuthority.Authoritative); var ticksSinceLastUpdateArray = transformGroup.GetComponentDataArray <TicksSinceLastTransformUpdate>(); var transformComponentArray = transformGroup.GetComponentDataArray <TransformInternal.Component>(); var bufferedTransformArray = transformGroup.GetBufferArray <BufferedTransform>(); var unityTransformArray = transformGroup.GetComponentArray <UnityEngine.Transform>(); var spatialEntityIdArray = transformGroup.GetComponentDataArray <SpatialEntityId>(); for (int i = 0; i < transformComponentArray.Length; ++i) { if (updateSystem .GetAuthorityChangesReceived(spatialEntityIdArray[i].EntityId, TransformInternal.ComponentId) .Count == 0) { continue; } var t = transformComponentArray[i]; var unityTransform = unityTransformArray[i]; unityTransform.position = t.Location.ToUnityVector3() + worker.Origin; unityTransform.rotation = t.Rotation.ToUnityQuaternion(); bufferedTransformArray[i].Clear(); ticksSinceLastUpdateArray[i] = new TicksSinceLastTransformUpdate(); } }
private void UpdateTransformData() { rigidbodyGroup.SetFilter(TransformInternal.ComponentAuthority.Authoritative); var ticksSinceLastUpdateArray = rigidbodyGroup.GetComponentDataArray <TicksSinceLastTransformUpdate>(); var transformComponentArray = rigidbodyGroup.GetComponentDataArray <TransformInternal.Component>(); var bufferedTransformArray = rigidbodyGroup.GetBufferArray <BufferedTransform>(); var rigidbodyArray = rigidbodyGroup.GetComponentArray <Rigidbody>(); var spatialEntityIdArray = rigidbodyGroup.GetComponentDataArray <SpatialEntityId>(); for (int i = 0; i < transformComponentArray.Length; ++i) { // todo this is not a correct constraint. Needs a the auth loss temporary exposed to correctly do this // alternatively this needs an authority changed component that is filled at the beginning of the tick if (updateSystem .GetAuthorityChangesReceived(spatialEntityIdArray[i].EntityId, TransformInternal.ComponentId) .Count == 0) { continue; } var t = transformComponentArray[i]; var rigidbody = rigidbodyArray[i]; rigidbody.MovePosition(t.Location.ToUnityVector3() + worker.Origin); rigidbody.MoveRotation(t.Rotation.ToUnityQuaternion()); rigidbody.AddForce(t.Velocity.ToUnityVector3() - rigidbody.velocity, ForceMode.VelocityChange); bufferedTransformArray[i].Clear(); ticksSinceLastUpdateArray[i] = new TicksSinceLastTransformUpdate(); } }
protected override unsafe void OnUpdate() { var deltaTime = UnityEngine.Time.deltaTime; var time = UnityEngine.Time.time; var skills = g.GetBufferArray <SkillElement>(); for (int i = 0; i < skills.Length; i++) { var dynamicBuffer = skills[i]; var ptr = (SkillElement *)dynamicBuffer.GetBasePointer(); for (int j = 0, length = dynamicBuffer.Length; j < length; ++j, ++ptr) { ptr->SinceLastTime += deltaTime; } } }
protected override void OnUpdate() { interpolationGroup.SetFilter(TransformInternal.ComponentAuthority.NotAuthoritative); var interpolationConfigArray = interpolationGroup.GetSharedComponentDataArray <InterpolationConfig>(); var bufferedTransformArray = interpolationGroup.GetBufferArray <BufferedTransform>(); var spatialEntityIdArray = interpolationGroup.GetComponentDataArray <SpatialEntityId>(); var transformComponentArray = interpolationGroup.GetComponentDataArray <TransformInternal.Component>(); var lastTransformArray = interpolationGroup.GetComponentDataArray <DeferredUpdateTransform>(); for (int i = 0; i < transformComponentArray.Length; ++i) { var config = interpolationConfigArray[i]; var transformBuffer = bufferedTransformArray[i]; var lastTransformApplied = lastTransformArray[i].Transform; if (transformBuffer.Length >= config.MaxLoadMatchedBufferSize) { transformBuffer.Clear(); } if (transformBuffer.Length == 0) { var currentTransformComponent = transformComponentArray[i]; if (currentTransformComponent.PhysicsTick <= lastTransformApplied.PhysicsTick) { continue; } lastTransformArray[i] = new DeferredUpdateTransform { Transform = currentTransformComponent }; var transformToInterpolateTo = ToBufferedTransform(currentTransformComponent); uint ticksToFill = math.max((uint)config.TargetBufferSize, 1); if (ticksToFill > 1) { var transformToInterpolateFrom = ToBufferedTransformAtTick(lastTransformApplied, transformToInterpolateTo.PhysicsTick - ticksToFill + 1); transformBuffer.Add(transformToInterpolateFrom); for (uint j = 0; j < ticksToFill - 2; ++j) { transformBuffer.Add(InterpolateValues(transformToInterpolateFrom, transformToInterpolateTo, j + 1)); } } transformBuffer.Add(transformToInterpolateTo); continue; } var updates = updateSystem .GetEntityComponentUpdatesReceived <TransformInternal.Update>(spatialEntityIdArray[i].EntityId); for (int j = 0; j < updates.Count; ++j) { var update = updates[j].Update; UpdateLastTransform(ref lastTransformApplied, update); lastTransformArray[i] = new DeferredUpdateTransform { Transform = lastTransformApplied }; if (!update.PhysicsTick.HasValue) { continue; } var transformToInterpolateTo = ToBufferedTransform(lastTransformApplied); var transformToInterpolateFrom = transformBuffer[transformBuffer.Length - 1]; uint lastTickId = transformToInterpolateFrom.PhysicsTick; // This could go backwards if authority changes quickly between two workers with different loads if (lastTickId >= transformToInterpolateTo.PhysicsTick) { continue; } uint ticksToFill = math.max(transformToInterpolateTo.PhysicsTick - lastTickId, 1); for (uint k = 0; k < ticksToFill - 1; ++k) { transformBuffer.Add(InterpolateValues(transformToInterpolateFrom, transformToInterpolateTo, k + 1)); } transformBuffer.Add(transformToInterpolateTo); } } }
protected override unsafe void OnUpdate() { // Segmentの個数を計算 var segmentCount = componentGroup.CalculateLength(); // TrailElementの個数を計算 var trailBufferArray = componentGroup.GetBufferArray <TrailBufferElement>(); var trailElementCount = 0; for (var i = 0; i < segmentCount; ++i) { trailElementCount += trailBufferArray[i].Length; } // 配列のサイズが足りなかったら新しく作り直す if (!trailElements.IsCreated || trailElements.Length < trailElementCount) { if (trailElements.IsCreated) { trailElements.Dispose(); } trailElements = new NativeArray <float3>(CalcWrappingArraySize(trailElementCount), Allocator.Persistent); trailElementBuffer?.Dispose(); trailElementBuffer = new ComputeBuffer(trailElements.Length, sizeof(TrailBufferElement)); } if (!segments.IsCreated || segments.Length < segmentCount) { if (segments.IsCreated) { segments.Dispose(); } segments = new NativeArray <int3>(CalcWrappingArraySize(segmentCount), Allocator.Persistent); segmentBuffer?.Dispose(); segmentBuffer = new ComputeBuffer(segments.Length, sizeof(TrailBufferElement)); } // UnsafePtrを取得する var offset = 0; var trailElementsPtr = (float3 *)trailElements.GetUnsafePtr(); var segmentsPtr = (int3 *)segments.GetUnsafePtr(); var entityArray = componentGroup.GetEntityArray(); // あらかじめ計算してあったSegmentの数(=パーティクルの数)だけループを回す for (var i = 0; i < segmentCount; ++i) { var trailBuffer = trailBufferArray[i]; var entity = entityArray[i]; var bufferLength = trailBuffer.Length; // TrailBufferの値をNativeArrayに複製していく UnsafeUtility.MemCpy(trailElementsPtr, trailBuffer.GetBasePointer(), sizeof(float3) * bufferLength); *segmentsPtr = new int3(offset, bufferLength, entity.Index); // Segmentにヘッダ情報を書き込む // ヘッダ用のオフセットを再計算しておく offset += bufferLength; // ポインタを進める segmentsPtr++; trailElementsPtr += bufferLength; } // ComputeBufferにNativeArrayの情報を渡す trailElementBuffer.SetData(trailElements); segmentBuffer.SetData(segments); // MaterialPropertyBlockに生成したBufferを渡す materialPropertyBlock.SetBuffer("_Positions", trailElementBuffer); materialPropertyBlock.SetBuffer("_Segments", segmentBuffer); // Segmentの数を渡しておく meshInstancedArgs.SetData(trailMesh, (uint)segmentCount); // Meshを描画する Graphics.DrawMeshInstancedIndirect( trailMesh, 0, Material, new Bounds(Vector3.zero, Vector3.one * 1000), meshInstancedArgs.Buffer, 0, materialPropertyBlock ); }