# Question
Title: Duplicate class errors when building app larger than 150mb with Android App Bundles
I have been trying to get Asset Bundles to work since my app is larger than 150MB, but the `Google -> Build Android App Bundle...` step keeps failing on me.

I am running Unity 2021.3.9f1 I tried both version 1.7 and 1.8 of the Google assetdelivery package, both broken.

I have 4 different errors. Has anyone dealt with these issues?

Error 1:

```
Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details

> Configure project :launcher
WARNING: The option setting 'android.enableR8=false' is deprecated.
It will be removed in version 5.0 of the Android Gradle plugin.
You will no longer be able to disable R8

> Task :launcher:preBuild UP-TO-DATE
> Task :unityLibrary:preBuild UP-TO-DATE
> Task :unityLibrary:preReleaseBuild UP-TO-DATE
> Task :unityLibrary:packageReleaseRenderscript NO-SOURCE
> Task :unityLibrary:compileReleaseRenderscript NO-SOURCE
> Task :launcher:extractProguardFiles UP-TO-DATE
> Task :unityLibrary:generateReleaseResValues UP-TO-DATE
> Task :launcher:preReleaseBuild UP-TO-DATE
> Task :unityLibrary:generateReleaseResources UP-TO-DATE
> Task :launcher:compileReleaseRenderscript NO-SOURCE
> Task :launcher:generateReleaseResValues UP-TO-DATE
> Task :launcher:generateReleaseResources UP-TO-DATE
> Task :launcher:createReleaseCompatibleScreenManifests UP-TO-DATE
> Task :launcher:extractDeepLinksRelease UP-TO-DATE
> Task :unityLibrary:packageReleaseResources UP-TO-DATE
> Task :unityLibrary:extractDeepLinksRelease UP-TO-DATE
> Task :unityLibrary:processReleaseManifest UP-TO-DATE
> Task :unityLibrary:compileReleaseLibraryResources UP-TO-DATE
> Task :unityLibrary:compileReleaseAidl NO-SOURCE
> Task :unityLibrary:generateReleaseBuildConfig UP-TO-DATE
> Task :unityLibrary:parseReleaseLocalResources UP-TO-DATE
> Task :unityLibrary:javaPreCompileRelease UP-TO-DATE
> Task :unityLibrary:processReleaseJavaRes NO-SOURCE
> Task :unityLibrary:bundleLibResRelease NO-SOURCE
> Task :unityLibrary:mergeReleaseShaders UP-TO-DATE
> Task :unityLibrary:compileReleaseShaders NO-SOURCE
> Task :unityLibrary:generateReleaseAssets UP-TO-DATE
> Task :launcher:checkReleaseDuplicateClasses FAILED
> Task :unityLibrary:packageReleaseAssets
> Task :unityLibrary:generateReleaseRFile UP-TO-DATE
16 actionable tasks: 2 executed, 14 up-to-date

UnityEditor.BuildPipeline:BuildPlayer (UnityEditor.BuildPlayerOptions)
Google.Android.AppBundle.Editor.Internal.BuildTools.AndroidBuilder:Build (UnityEditor.BuildPlayerOptions) (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/BuildTools/AndroidBuilder.cs:178)
Google.Android.AppBundle.Editor.Internal.BuildTools.AppBundleBuilder:BuildAndroidPlayer (UnityEditor.BuildPlayerOptions) (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/BuildTools/AppBundleBuilder.cs:179)
Google.Android.AppBundle.Editor.Internal.AppBundlePublisher:Build (Google.Android.AppBundle.Editor.Internal.BuildTools.AppBundleBuilder,Google.Android.AppBundle.Editor.Internal.AppBundlePublisher/AppBundleBuildSettings) (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/AppBundlePublisher.cs:175)
Google.Android.AppBundle.Editor.Internal.AppBundlePublisher:Build () (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/AppBundlePublisher.cs:139)
Google.Android.AppBundle.Editor.Internal.AppBundleEditorMenu:BuildAndroidAppBundle () (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/AppBundleEditorMenu.cs:66)

```

Error 2:

```
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':launcher:checkReleaseDuplicateClasses'.
> 1 exception was raised by workers:
  java.lang.RuntimeException: Duplicate class com.google.android.play.core.assetpacks.AssetLocation found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.AssetPackException found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.AssetPackExtractionService found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.AssetPackLocation found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.AssetPackManager found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.AssetPackManagerFactory found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.AssetPackState found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.AssetPackStateUpdateListener found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.AssetPackStates found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.ExtractionForegroundService found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.NativeAssetPackStateUpdateListener found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.model.AssetPackErrorCode found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.model.AssetPackStatus found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.model.AssetPackStorageMethod found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.common.IntentSenderForResultStarter found in modules com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:) and com.google.android.play.core-common-2.0.0-runtime.jar (:com.google.android.play.core-common-2.0.0:)
  Duplicate class com.google.android.play.core.common.LocalTestingException found in modules com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:) and com.google.android.play.core-common-2.0.0-runtime.jar (:com.google.android.play.core-common-2.0.0:)
  Duplicate class com.google.android.play.core.common.PlayCoreDialogWrapperActivity found in modules com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:) and com.google.android.play.core-common-2.0.0-runtime.jar (:com.google.android.play.core-common-2.0.0:)
  Duplicate class com.google.android.play.core.listener.StateUpdatedListener found in modules com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:) and com.google.android.play.core-common-2.0.0-runtime.jar (:com.google.android.play.core-common-2.0.0:)

  Go to the documentation to learn how to Fix dependency resolution errors.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 20s
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8

UnityEditor.BuildPipeline:BuildPlayer (UnityEditor.BuildPlayerOptions)
Google.Android.AppBundle.Editor.Internal.BuildTools.AndroidBuilder:Build (UnityEditor.BuildPlayerOptions) (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/BuildTools/AndroidBuilder.cs:178)
Google.Android.AppBundle.Editor.Internal.BuildTools.AppBundleBuilder:BuildAndroidPlayer (UnityEditor.BuildPlayerOptions) (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/BuildTools/AppBundleBuilder.cs:179)
Google.Android.AppBundle.Editor.Internal.AppBundlePublisher:Build (Google.Android.AppBundle.Editor.Internal.BuildTools.AppBundleBuilder,Google.Android.AppBundle.Editor.Internal.AppBundlePublisher/AppBundleBuildSettings) (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/AppBundlePublisher.cs:175)
Google.Android.AppBundle.Editor.Internal.AppBundlePublisher:Build () (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/AppBundlePublisher.cs:139)
Google.Android.AppBundle.Editor.Internal.AppBundleEditorMenu:BuildAndroidAppBundle () (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/AppBundleEditorMenu.cs:66)

```

Error 3:

```
CommandInvokationFailure: Gradle build failed.
C:\Program Files\Unity\Hub\Editor\2021.3.9f1\Editor\Data\PlaybackEngines\AndroidPlayer\OpenJDK\bin\java.exe -classpath "C:\Program Files\Unity\Hub\Editor\2021.3.9f1\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\gradle\lib\gradle-launcher-6.1.1.jar" org.gradle.launcher.GradleMain "-Dorg.gradle.jvmargs=-Xmx4096m" "bundleRelease"

stderr[

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':launcher:checkReleaseDuplicateClasses'.
> 1 exception was raised by workers:
  java.lang.RuntimeException: Duplicate class com.google.android.play.core.assetpacks.AssetLocation found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.AssetPackException found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.AssetPackExtractionService found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.AssetPackLocation found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.AssetPackManager found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.AssetPackManagerFactory found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.AssetPackState found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.AssetPackStateUpdateListener found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.AssetPackStates found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.ExtractionForegroundService found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.NativeAssetPackStateUpdateListener found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.model.AssetPackErrorCode found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.model.AssetPackStatus found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.assetpacks.model.AssetPackStorageMethod found in modules com.google.android.play.asset-delivery-2.0.0-runtime.jar (:com.google.android.play.asset-delivery-2.0.0:) and com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:)
  Duplicate class com.google.android.play.core.common.IntentSenderForResultStarter found in modules com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:) and com.google.android.play.core-common-2.0.0-runtime.jar (:com.google.android.play.core-common-2.0.0:)
  Duplicate class com.google.android.play.core.common.LocalTestingException found in modules com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:) and com.google.android.play.core-common-2.0.0-runtime.jar (:com.google.android.play.core-common-2.0.0:)
  Duplicate class com.google.android.play.core.common.PlayCoreDialogWrapperActivity found in modules com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:) and com.google.android.play.core-common-2.0.0-runtime.jar (:com.google.android.play.core-common-2.0.0:)
  Duplicate class com.google.android.play.core.listener.StateUpdatedListener found in modules com.google.android.play.core-1.10.3-runtime.jar (:com.google.android.play.core-1.10.3:) and com.google.android.play.core-common-2.0.0-runtime.jar (:com.google.android.play.core-common-2.0.0:)

  Go to the documentation to learn how to Fix dependency resolution errors.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 20s
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
]
stdout[
Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details

> Configure project :launcher
WARNING: The option setting 'android.enableR8=false' is deprecated.
It will be removed in version 5.0 of the Android Gradle plugin.
You will no longer be able to disable R8

> Task :launcher:preBuild UP-TO-DATE
> Task :unityLibrary:preBuild UP-TO-DATE
> Task :unityLibrary:preReleaseBuild UP-TO-DATE
> Task :unityLibrary:packageReleaseRenderscript NO-SOURCE
> Task :unityLibrary:compileReleaseRenderscript NO-SOURCE
> Task :launcher:extractProguardFiles UP-TO-DATE
> Task :unityLibrary:generateReleaseResValues UP-TO-DATE
> Task :launcher:preReleaseBuild UP-TO-DATE
> Task :unityLibrary:generateReleaseResources UP-TO-DATE
> Task :launcher:compileReleaseRenderscript NO-SOURCE
> Task :launcher:generateReleaseResValues UP-TO-DATE
> Task :launcher:generateReleaseResources UP-TO-DATE
> Task :launcher:createReleaseCompatibleScreenManifests UP-TO-DATE
> Task :launcher:extractDeepLinksRelease UP-TO-DATE
> Task :unityLibrary:packageReleaseResources UP-TO-DATE
> Task :unityLibrary:extractDeepLinksRelease UP-TO-DATE
> Task :unityLibrary:processReleaseManifest UP-TO-DATE
> Task :unityLibrary:compileReleaseLibraryResources UP-TO-DATE
> Task :unityLibrary:compileReleaseAidl NO-SOURCE
> Task :unityLibrary:generateReleaseBuildConfig UP-TO-DATE
> Task :unityLibrary:parseReleaseLocalResources UP-TO-DATE
> Task :unityLibrary:javaPreCompileRelease UP-TO-DATE
> Task :unityLibrary:processReleaseJavaRes NO-SOURCE
> Task :unityLibrary:bundleLibResRelease NO-SOURCE
> Task :unityLibrary:mergeReleaseShaders UP-TO-DATE
> Task :unityLibrary:compileReleaseShaders NO-SOURCE
> Task :unityLibrary:generateReleaseAssets UP-TO-DATE
> Task :launcher:checkReleaseDuplicateClasses FAILED
> Task :unityLibrary:packageReleaseAssets
> Task :unityLibrary:generateReleaseRFile UP-TO-DATE
16 actionable tasks: 2 executed, 14 up-to-date
]
exit code: 1
UnityEditor.Android.Command.WaitForProgramToRun (UnityEditor.Utils.Program p, UnityEditor.Android.Command+WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg) (at <5160fdea082d4c479eac116da4ffc2de>:0)
UnityEditor.Android.Command.Run (System.Diagnostics.ProcessStartInfo psi, UnityEditor.Android.Command+WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg) (at <5160fdea082d4c479eac116da4ffc2de>:0)
UnityEditor.Android.Command.Run (System.String command, System.String args, System.String workingdir, UnityEditor.Android.Command+WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg) (at <5160fdea082d4c479eac116da4ffc2de>:0)
UnityEditor.Android.AndroidJavaTools.RunJava (System.String args, System.String workingdir, System.Action`1[T] progress, System.String error) (at <5160fdea082d4c479eac116da4ffc2de>:0)
UnityEditor.Android.GradleWrapper.Run (UnityEditor.Android.AndroidJavaTools javaTools, Unity.Android.Gradle.AndroidGradle androidGradle, System.String workingdir, System.String task, System.Action`1[T] progress) (at <5160fdea082d4c479eac116da4ffc2de>:0)
Rethrow as GradleInvokationException: Gradle build failed
UnityEditor.Android.GradleWrapper.Run (UnityEditor.Android.AndroidJavaTools javaTools, Unity.Android.Gradle.AndroidGradle androidGradle, System.String workingdir, System.String task, System.Action`1[T] progress) (at <5160fdea082d4c479eac116da4ffc2de>:0)
UnityEditor.Android.PostProcessor.Tasks.BuildGradleProject.Execute (UnityEditor.Android.PostProcessor.PostProcessorContext context) (at <5160fdea082d4c479eac116da4ffc2de>:0)
UnityEditor.Android.PostProcessor.PostProcessRunner.RunAllTasks (UnityEditor.Android.PostProcessor.PostProcessorContext context) (at <5160fdea082d4c479eac116da4ffc2de>:0)
Rethrow as BuildFailedException: Exception of type 'UnityEditor.Build.BuildFailedException' was thrown.
UnityEditor.Android.PostProcessor.CancelPostProcess.AbortBuild (System.String title, System.String message, System.Exception ex) (at <5160fdea082d4c479eac116da4ffc2de>:0)
UnityEditor.Android.PostProcessor.PostProcessRunner.RunAllTasks (UnityEditor.Android.PostProcessor.PostProcessorContext context) (at <5160fdea082d4c479eac116da4ffc2de>:0)
UnityEditor.Android.PostProcessAndroidPlayer.PostProcess (UnityEditor.Modules.BuildPostProcessArgs args, AndroidPlayerBuildProgram.Data.AndroidPlayerBuildProgramOutput buildProgramOutput) (at <5160fdea082d4c479eac116da4ffc2de>:0)
UnityEditor.Android.AndroidBuildPostprocessor.PostProcess (UnityEditor.Modules.BuildPostProcessArgs args, UnityEditor.BuildProperties& outProperties) (at <5160fdea082d4c479eac116da4ffc2de>:0)
UnityEditor.PostprocessBuildPlayer.Postprocess (UnityEditor.BuildTargetGroup targetGroup, UnityEditor.BuildTarget target, System.Int32 subtarget, System.String installPath, System.String companyName, System.String productName, System.Int32 width, System.Int32 height, UnityEditor.BuildOptions options, UnityEditor.RuntimeClassRegistry usedClassRegistry, UnityEditor.Build.Reporting.BuildReport report) (at <0d6ce211ebbc47e1a35a84c3672ff58f>:0)
UnityEditor.BuildPipeline:BuildPlayer(BuildPlayerOptions)
Google.Android.AppBundle.Editor.Internal.BuildTools.AndroidBuilder:Build(BuildPlayerOptions) (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/BuildTools/AndroidBuilder.cs:178)
Google.Android.AppBundle.Editor.Internal.BuildTools.AppBundleBuilder:BuildAndroidPlayer(BuildPlayerOptions) (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/BuildTools/AppBundleBuilder.cs:179)
Google.Android.AppBundle.Editor.Internal.AppBundlePublisher:Build(AppBundleBuilder, AppBundleBuildSettings) (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/AppBundlePublisher.cs:175)
Google.Android.AppBundle.Editor.Internal.AppBundlePublisher:Build() (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/AppBundlePublisher.cs:139)
Google.Android.AppBundle.Editor.Internal.AppBundleEditorMenu:BuildAndroidAppBundle() (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/AppBundleEditorMenu.cs:66)

```

Error 4:

```
Build error: Build failed with 4 error(s)
UnityEngine.Debug:LogErrorFormat (string,object[])
Google.Android.AppBundle.Editor.Internal.BuildTools.BuildToolLogger:DisplayErrorDialog (string) (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/BuildTools/BuildToolLogger.cs:95)
Google.Android.AppBundle.Editor.Internal.BuildTools.AndroidBuilder:Build (UnityEditor.BuildPlayerOptions) (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/BuildTools/AndroidBuilder.cs:205)
Google.Android.AppBundle.Editor.Internal.BuildTools.AppBundleBuilder:BuildAndroidPlayer (UnityEditor.BuildPlayerOptions) (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/BuildTools/AppBundleBuilder.cs:179)
Google.Android.AppBundle.Editor.Internal.AppBundlePublisher:Build (Google.Android.AppBundle.Editor.Internal.BuildTools.AppBundleBuilder,Google.Android.AppBundle.Editor.Internal.AppBundlePublisher/AppBundleBuildSettings) (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/AppBundlePublisher.cs:175)
Google.Android.AppBundle.Editor.Internal.AppBundlePublisher:Build () (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/AppBundlePublisher.cs:139)
Google.Android.AppBundle.Editor.Internal.AppBundleEditorMenu:BuildAndroidAppBundle () (at Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/AppBundleEditorMenu.cs:66)

```

# Answer
> 0 votes
So it turns out that Firebase unitypackage was causing conflicts with Google's App bundle deliver unitypackage. I did not get to the bottom of the conflict, but I did remove the Firebase files and I was able to install and use the latest Play Asset Delivery (1.8.1 at the time of this writing).

---
Tags: unity, android, assetbundle
---


# Question
Title: How to emulate the look of loading ZX Spectrum title screens in Unity
I am looking to replicate the style of screen loading as seen on the ZX Spectrum in Unity. Not the stripes of colors in the background. Just the title image loading.

Specifically the way it looks in this video:

Underwurlde Loading Screen - ZX Spectrum

I like the way it seems to load the image, top-down, from left to right, in chunks. But I am not sure how to accomplish this or what I should even search for to find the answer.

Ideally I would like to update the screen this way on each frame of the game, with the next frame "drawing" the screen overtop of the previous frame. It would also be great to be able to control the speed and amount of screen it loads per frame.

Does anyone have any tips on the best way to accomplish this?

# Answer
> 1 votes
We can write a shader that displays blocks of one texture over another, something like this:

```
Shader "Unlit/ZXLoad"
{
    Properties
    {
        _MainTex ("Loading Texture", 2D) = "white" {}
        _UnderTex ("Underlying Texture", 2D) = "black" {}
        _RowCount ("Rows", int) = 16
        _ColCount ("Columns", int) = 32
        _Progress ("Load Progress", Range(0, 1)) = 0.5
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            sampler2D _UnderTex;
            float4 _MainTex_ST;
            int _RowCount;
            int _ColCount;
            half _Progress;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // Number each block in the grid
                // from 0 to _RowCount*_ColCount - 1,
                // and find which block this pixel is in.
                float block = floor(i.uv.x * _ColCount)
                            + floor((1.0f - i.uv.y) * _RowCount) * _ColCount;

                // If it's an "Early" block, already loaded by the
                // time we reach _Progress, sample the main texture.
                if (block < _Progress * _RowCount * _ColCount) {
                    return tex2D( _MainTex, i.uv);

                // Otherwise, sample the underlying texture.
                return tex2D( _UnderTex, i.uv);
            }
            ENDCG
        }
    }
}

```

You can use this to make a material that accepts two textures: one to show underneath and one on top, with a "Load Progress" slider you can dial back and forth to show more or less of the texture being "loaded". You can use this material on a quad or UI image/raw image component to display your pseudo-loading output.

You can animate this any way you want in your C# script, using `Material.SetFloat("_Progress", loadAmount)` (or the integer version, for better performance) to animate the progress counter forward.

You can use a camera that writes its output to a `RenderTexture` to capture the images you want to display for each "frame", and use those textures as the loading / underlying textures of this material, swapping between them (and swapping their order in the material) on alternate renders.

---
Tags: unity, shaders, graphics
---


# Question
Title: How to spread circles evenly around a point?
In my game there's a part where a bunch of circles need to evenly spread around a point. Like in this demo below:

```
const rng = (min, max) => Math.random() * (max - min + 1) + min;

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");

ctx.strokeStyle = "#000";
ctx.lineWidth = 4;
ctx.fillStyle = "#ff0000";

function drawCircle(c) {
  ctx.beginPath();
  ctx.arc(c.x, c.y, c.r, 0, 2 * Math.PI);
  ctx.stroke();
  ctx.fill();
}

class Circle {
  constructor(x, y, r) {
    this.x = x;
    this.y = y;
    this.r = r;
    this.vX = 0;
    this.vY = 0;
  }
}

const circles = [];

for (let i = 0; i < 300; i++) {
  circles.push(new Circle(rng(0, canvas.width), rng(0, canvas.height), rng(12, 14)));
}

function processCollision(c1, c2) {
  const deltaX = c2.x - c1.x;
  const deltaY = c2.y - c1.y;

  const sumRadius = c1.r + c2.r;
  const centerDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);

  if (centerDistance === 0 || centerDistance > sumRadius) { return; } // not colliding

  const circleDistance = centerDistance - sumRadius;

  const aX = deltaX / centerDistance;
  const aY = deltaY / centerDistance;

  const force = 5;

  c1.vX += aX * circleDistance * force;
  c1.vY += aY * circleDistance * force;
}

function update() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  for (const c of circles) {
    c.vX = (canvas.width / 2) - c.x; // move towards center x
    c.vY = (canvas.height / 2) - c.y; // move towards center y
  }

  for (const c1 of circles) {
    for (const c2 of circles) {
      c1 !== c2 && processCollision(c1, c2);
    }
  }

  for (const c of circles) {
    c.x += c.vX * (1 / 60);
    c.y += c.vY * (1 / 60);

    drawCircle(c);
  }
}

setInterval(update, 16.6666);
```

```
<canvas width="600" height="600" style="border:1px solid #d3d3d3;">
```

This works, but you'll notice most of the circles overlap each other, especially the ones in the center. I'm looking for a solution where the circles mostly don't overlap at all (a little is okay).

I tried adjusting the `force` parameter, and while that works slightly, it also causes a lot of shake, jitter, and jank. I would like everything to remain smooth and calm, and I am having a lot of trouble doing that. Is there any way to have the circles mostly evenly spread around the center point without massively colliding with one another?

# Answer
Some quick optimizations you can make are to process collisions in a double-sided way, so you don't have to process them twice each, and save your square roots for only the cases where you need them:

```
function processCollision(c1, c2) {
  const deltaX = c2.x - c1.x;
  const deltaY = c2.y - c1.y;

  const interactionRange = 2;

  // Note if your circles all have the same size, you can
  // save sumRadius as a constant externally, and not re-compute it.
  const sumRadius = c1.r + c2.r + interactionRange;
  const squaredDistance = deltaX * deltaX + deltaY * deltaY;

  if (squaredDistance === 0 || squaredDistance > sumRadius * sumRadius) { return; } // not colliding

  const centerDistance = Math.sqrt(squaredDistance);

  const circleDistance = centerDistance - sumRadius;

  const force = 5;

  const aX = circleDistance * force * deltaX / centerDistance;
  const aY = circleDistance * force * deltaY / centerDistance;

  c1.vX += aX;
  c1.vY += aY;

  c2.vX -= aX;
  c2.vY -= aY;
}

```

Next, keep some velocity from frame to frame, and treat the inward pull as a competing acceleration:

```
function update() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  const inertia = 0.8;
  const attraction = 0.1;

  for (const c of circles) {
    c.vX *= inertia;
    c.vY *= inertia;

    c.vX += attraction * ((canvas.width / 2) - c.x);
    c.vY += attraction * ((canvas.height / 2) - c.y);
  }

  // Process each spring just once.
  for (let i = 0; i < circleCount; i++) {
    for (let j = i+1; j < circleCount; j++) {
      processCollision(circles[i], circles[j]);
    }
  }

  for (const c of circles) {
    c.x += c.vX * (1 / 60);
    c.y += c.vY * (1 / 60);

    drawCircle(c);
  }
}

```

Increase the `interactionRange` parameter to give more of a buffer between circles where the repulsion force can ramp up, and increase the `force` parameter to make the ramp steeper, so you get a stronger push.

If it jerks and jitters too much, reduce the `inertia` parameter to sap more energy out of the system.

If the pull into the center is too strong, reduce the `attraction` parameter. You could even make this attraction ignore distance, so you don't get tighter squeezes at the perimeter than near the center.
> 1 votes

---
Tags: collision-detection, physics, javascript, geometry, html-canvas
---


# Question
Title: How to find out which biome the player is currently on
I'm using Godot 3.5 and OpenSimplexNoise to generate my 2D topdown world with right (auto)tiles. How can I detect on which biome I'm currently standing on?

This is how I generate my map (in some way simplified pseudo code)

```
for (x : WORLD_SIZE_X)
    for (y : WORLD_SIZE_Y)
         m_temperature[{x, y}] = openSimplexNoise.getNoise2D(x, y);

for (x : WORLD_SIZE_X)
{
    for (y : WORLD_SIZE_Y)
    {
         float temperature = m_temperature[{x, y}];
         if (temperature > 0 && temperature < 0.5) // forest
             m_tileset.setCell({x, y}, forestCellID);
         else if (temperature > 0.5 && temperature < 0.8) //desert
             m_tileset.setCell({x, y}, desertCellID);
         else
             //etc
    }
 }

```

# Answer
> 0 votes
So the answer is my code. As the @DMGregory pointed in my question post comments I could use my determination function to find out which biome I can find. Like this:

```
enum BiomeType { SNOWY_WASTELANDS, //etc. }
public BiomeType getBiomeType(Vector2 position)
{
        float moisture = m_moisture[position];
        float temperature = m_temperature[position];

        if (moisture >= 0.0f && moisture <= 0.3f)
        {
            if (temperature <= 0.3f)
                return BiomeType.SNOWY_WASTELANDS;
            else if (temperature <= 0.6f)
                return BiomeType.Biome2;
            else
                return BiomeType.Biome3;
       }
       else
       {
            if (moisture <= 0.6f)
                return BiomeType.Blabla;
            else if (moisture <= 0.8f)
                return BiomeType.Blablabla2;
            else
                return BiomeType.Blablabla3;
        }
}

```

And I could always calculate it on loading times so I don't have to do it every time when I move like so:

```
public void _Ready()
{
    m_biomeInfo = new Dictionary<Vector2, BiomeType>();
    for (int x = 0; x < WORLD_WIDTH; x++)
    {
       for (int y = 0; y < WOLRD_HEIGHT; y++)
       {
           Vector2 position = new Vector2(x, y);
           BiomeType biomeType;
           //calculate biome for position here
           m_biomeInfo[position] = biomeType;
       }
    }
}

public BiomeType getBiomeType(Vector2 position)
{
     return m_biomeInfo[position];
}

```

This wouldn't work for infinite worlds, so I think the only way to calculate it on fly. It depends on the game tho for example you could connect biomes with right tiles and find out which current tile is player standing on. This would work while your ground tiles are unique to biome like "DESERT\_GROUND\_TILE" in my case.

---
Tags: procedural-generation, tiles, godot
---


# Question
Title: Algorithm for taking the shortest path between two XY coordinates
I am making a simple game in Phaser (but the library doesn't really matter).

I have an enemy that is moving towards the player on a 2 dimensional grid. I have written some code that makes the enemy move towards the player:

```
moveEnemy(enemy){
    var playerX = getPlayerX(); // a number
    var playerY = getPlayerY(); // a number

    // if the enemy X or Y coordinate is smaller or larger than the players,
    // increase or decrease the enemy X or Y to move closer.
    var newX = enemy.x > playerX ? enemy.x - 0.2 : enemy.x + 0.2;
    var newY = enemy.y > playerY ? enemy.y - 0.2 : enemy.y + 0.2;
    enemy.setPosition(newX, newY);
}

```

I expected this code to move the enemy towards the player in the shortest route possible. However, I get the following situation:

The green route is what I expected the enemy to take. In reality, the enemy follows the red line: first it goes down in a 45 degree angle, before going towards the player in a straight horizontal line. I'm at a loss how to make my enemies move along the green line.

# Answer
> 3 votes
Your code makes him move vertical and horizontal if needed.

He moves the same speed both vertical and horizontal, that's why you only get a 45 degree angle.

He moves like this until there is no need to move vertical, and he only moves horizontal the last bit.

To solve this you need first to calculate `deltaX = enemy.x - playerX` and `deltaY` between the two points, and move the portion of distance in each direction, and he will move directly from A to B.

You'll need to know the distance to set constant speed. Find it with `theDistance = Math.sqrt(dX*dX+dY*dY)` with the squareroot-method.

I suggest unifying the direction by dividing `deltaX/theDistance` over the distance to get your direction, then you can just multiply this with the speed you want on the enemy.

---
Tags: javascript, coordinates, phaser
---


# Question
Title: How do I calculate the direction of an object relative to the another object's view
Here is a diagram of what I'm looking for:

I am trying to find the math solution to determine where that smaller circle is relative to the bigger circle's view.

I thought that the easiest way would be to get a vector between the small circle and the big circle and a second vector that is pointing out from the bigger circle's base to a little in front of its view (normalized of course), and then do a dot product to get the angle... but I have no idea how to get the small pointing out vector from the big circle's base to its view direction in front of it.

I'm not interested in using a Unity pre-implemented function to resolve this. What do I need to calculate this, or maybe you have a better idea for how to resolve this?

# Answer
> 1 votes
The easiest way to do this would be:

```
Vector3 localPoint = bigCircle.transform.InverseTransformPoint(
                          smallCircle.transform.position
                     );

```

This `local` variable now holds the position of the small circle within the big circle's local coordinate system. That is, a coordinate system where (0, 0, 0) is the origin of the big circle, +z points to the big circle's "forward" direction (blue arrow of the local transformation gizmo), +x points to its right (red arrow), and +y points to the circle's up (green arrow).

If you then want to get a signed angle in the big circle's horizontal plane, that could look like:

```
float angleDegrees = Mathf.Atan2(localPoint.x, localPoint.z) * Mathf.Rad2Deg;

```

That will give you a bearing angle where 0 = directly ahead / "N", 90 = to the right / "E", 180 = exactly behind / "S".

Since you say you want to calculate this with math, not use a pre-built function, what `InverseTransformPoint` is doing is taking `bigCircle.transform.localToWorldMatrix` and inverting it to get `worldToLocalMatrix`, then multiplying the provided point by this matrix:

```
 Vector3 localPoint = bigCircle.trandform.worldToLocalMatrix
                      * smallCircle.transform.position;

```

You can get a similar result without matrix math like so:

```
// Remove bigCircle's translation.
Vector3 worldOffset = smallCircle.transform.position - bigCircle.transform.position;

// Remove bigCircle's rotation.
Quaternion antiRotation = Quaternion.Inverse(bigCircle.transform.rotation);
Vector3 localOffsetScaled = antiRotation * worldOffset;

// Remove bigCircle's scale (if applicable).
Vector3 antiScale = bigCircle.transform.localScale;
antiScale = new Vector3(1f/antiScale.x, 1f/antiScale.y, 1f/antiScale.z);
Vector3 localOffsetUnscaled = Vector3.Scale(localOffsetScaled, antiScale);

```

---
Tags: unity, 3d, mathematics, trigonometry
---


# Question
Title: Increasing Recoil Over Time With 'Diminishing Returns'
I have a recoil system where per shot, the recoil value increases. I want the recoil to increase more quickly for the first 10 or so shots, then settle to a slower increase rate that then remains constant.

I have another value, let's call it "Damping", which dampens screen shake and such. This is required because I have many other related effects like screen shake which increase with the more recoil there is. The *lower* Damping is, the more it diminishes these effects. So I need Damping to *decrease* while recoil increases. Unlike Recoil, I need to gradually decrease for the first 10 shots, then the rate of decrease needs to get faster.

The other issue is that I need to adjust these curves depending on the weapons ROF. The lower the ROF, the higher the rate of Recoil increase needs to be (and conversely, the faster the rate of decrease for Damping).

I can do it all manually by multiplying recoil and damping by a factor to increase/decrease them per shot, and change the rates of increase/decrease for every x amount of shots, but this is obviously not ideal as it requires a lot of repetitive code and manual tweaking.

I'm using Unity, C#. I'm doing all the increasing and decreasing in void `Update()`.

What sort of formulas could I use to achieve these two curves? I've tried searching for "recoil curves" and looked at many tutorials for various recoil systems but none really apply to what I am trying to do or how my recoil works.

# Answer
Whenever I need a formula that describes a curve, and the curve isn't extremely simple to describe with code, I use an Animation Curve. Despite the name, this feature is useful for any kind of 2D curve, not just for animation. The animation curve's `Evaluate()` function takes in a 'time' (x-axis position) as the input and returns a 'value' (y-axis position); in other words, `y = curve.Evaluate(x)` is equivalent to the standard mathematical notation for a graph function, `y = f(x)`.

Animation curves have several advantages over coded curves - it's easy to understand the general shape of the curve at a glance, it's easy to make big changes to the curve without having to work out new equations, and the performance is excellent. I prefer to set up the curve so that both axes are normalized; i.e., the minimum value is 0 and the maximum value is 1. You can then normalize your inputs and scale your outputs in script.

```
[SerializeField] private AnimationCurve recoilCurve;
[SerializeField] private AnimationCurve dampeningCurve;
[Tooltip("Scales Y axis of recoil curve")]
[SerializeField] private float maxRecoil = 10;
[Tooltip("Scales Y axis of dampening curve")]
[SerializeField] private float maxDampening = 1;
[Tooltip("Recoil and dampening stop changing once we've fired this many shots")]
[SerializeField] private int maxShotsFiredThreshold = 30;
[Tooltip("Recoil is higher if the weapon shoots slower than this and lower if the weapon shoots faster than this")]
[SerializeField] private float averageROF = 30;

[SerializeField] private Weapon weapon;
private int shotsFired;

private void Update() {
    //ratio of shots fired to max, i.e. our position on the x-axis
    float t = Mathf.Clamp01(shotsFired / (float)maxShotsFiredThreshold);
    float rofFactor = averageROF / weapon.RateOfFire;

    //evaluate gives us the y-coordinate for the given x-coordinate,
    //which we then scale from a normalized value to our final value
    float recoil = maxRecoil * recoilCurve.Evaluate(t) * rofFactor;
    float dampening = maxDampening * dampeningCurve.Evaluate(t) / rofFactor;
}

```

In this example we define a maximum shots fired threshold (beyond which the curves stop changing). The `t` variable is our normalized number of shots fired, which we calculate by dividing the number of shots fired so far by the maximum threshold. We use `t` as the input for the `Evaluate()` function (meaning it specifies the X value along the curve) and `Evaluate()` function returns the Y-value for that input. Since we used a normalized range of values for the Y-axis, we then scale the output by `maxDamping` / `maxRecoil`, and finally apply the rate-of-fire (ROF) factor.
> 2 votes

---
Tags: unity, c#, mathematics, first-person-shooter, curves
---


# Question
Title: Navmesh agents trying to go to destroyed objects
I am still working on the RTS and have added a system that allows enemies to randomly wander. However, when multiple enemies fight one of my units, they will just clump up Afterwords instead of going back to wandering. Here is the code for their pathfinding.

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.UIElements;

public class Human : MonoBehaviour
{
    public List<GameObject> axolotls;
    Detector detector;
    NavMeshAgent myAgent;
    Vector3 axolotlPosition;
    float lowestDistance = 0;
    public GameObject closestAxolotl;
    Vector3 randomWander;
    Vector3 lastRandomDestination;
    // Start is called before the first frame update
    void Start()
    {
        detector = this.gameObject.GetComponentInChildren<Detector>();
        myAgent = this.gameObject.GetComponent<NavMeshAgent>();

    }

    // Update is called once per frame
    void Update()
    {

        axolotls = detector.axolotls;

        // Don't put this check inside your for loop:
        // code inside the loop only executes if Count is > 0
        if (axolotls.Count == 0 && myAgent.destination != lastRandomDestination)
        {
            myAgent.SetDestination(randomDestination(randomWander));
        }
        else
        {

            // Initialize our search to the worst possibility:
            // no target, infinitely far away! (Literally ANYTHING else is better!)
            float lowestScore = Mathf.Infinity;
            GameObject closest = null;

            Vector3 myPosition = transform.position;
            foreach (var axolotl in axolotls)
            {
                // Skip destroyed axolotls (better: make sure they're not in the list!)
                if (axolotl == null) continue;

                // Don't pay for a square root we don't need.
                float score = (axolotl.transform.position - myPosition).sqrMagnitude;

                if (score < lowestScore)
                {
                    closest = axolotl;
                    lowestScore = score;
                }
            }

            // "closest" now contains the nearest axolotl.
            myAgent.SetDestination(closest.transform.position);

        }

    }
    public void removeAxolotl(GameObject axolotl)
    {
        detector.axolotls.Remove(axolotl);
        if(closestAxolotl == axolotl)
        {
            closestAxolotl = null;
            lowestDistance = 0;
        }
    }
    Vector3 randomDestination(Vector3 randomDestination)
    {
        randomDestination.x = Random.Range(-27, 27);
        randomDestination.z = Random.Range(-27, 27);
        lastRandomDestination = randomDestination;
        Debug.Log("setting destination");
        return randomDestination;
    }
}

```

# Answer
> 0 votes
> When you remove an Axolotl, on which human(s) do you call removeAxolotl()? – DMGregory♦

> Only the human who lands the killing shot. Do you have any suggestions for making it run on all of them? – Crystalline787

That's a problem, because this method contains a very important piece of code:

```
closestAxolotl = null;
lowestDistance = 0;

```

All your other humans who were attacking that axolotl don't get their `lowestDistance` variable reset to zero.

Since you only reset this variable to a higher number when its value is exactly zero, and you only change targets to ones whose distance is *lower* than the current `lowestDistance`, if a human was close to an axolotl that died without being the one to land the killing blow, it will refuse to switch targets to *any* axolotl farther away than that now-corpse.

You can make this code much more robust (and more efficient) by not storing `lowestDistance` between frames. Less state to reset!

```
// Don't put this check inside your for loop:
// code inside the loop only executes if Count is > 0
if (axolotls.Count == 0) {
    if (Time.time - lastWanderTime > wanderDuration) {
       myAgent.SetDestination(randomDestination(randomWander));
       lastWanderTime = Time.time;
    }
} else {

    // Initialize our search to the worst possibility:
    // no target, infinitely far away! (Literally ANYTHING else is better!)
    float lowestScore = float.positiveInfinity;
    Axolotl closest = null;

    Vector3 myPosition = transform.position;
    foreach (var axolotl in axolotls) {
        // Skip destroyed axolotls (better: make sure they're not in the list!)
        if (axolotl == null) continue;

        // Don't pay for a square root we don't need.
        float score = (axolotl.transform.position - myPosition).sqrMagnitude;

        if (score < lowestScore) {
            closest = axolotl;
            lowestScore = score;
        }
    }

    // "closest" now contains the nearest axolotl.
}

```

There are some other things in your code that don't make sense, like this line, which removes an axolotl from a list, only if it wasn't in that list:

```
if (!axolotls.Contains(closestAxolotl))
{
    axolotls.Remove(closestAxolotl);
    // ...

```

...so I think you should take a thorough proofreading pass through the whole file, or maybe get a friend to do some code review with you, to make sure you don't have more bugs lurking in there.

---
Tags: unity, c#, random, navmesh
---


# Question
Title: How to make a shader which alpha blends against only itself, and is opaque otherwise?
Imagine a scene with a minecraft style world held in a bounded container and is being viewed from a isometric 3rd person camera that has a fixed orientation. I want to create a shader that expresses as much information the player might want to know, e.g. x-ray vision of tunnels and areas behind walls that the player might be in close proximity to but would normally be occluded by the terrain. Objects (such as the player) can be inside the object and should be blended nicely with the x-rayed layers.

Here is a rough illustration to convey the idea:

This is how it would look if the shader did the following:

* Render back to front
* The first (furthest depth) fragment has an alpha of 1, and after that each overlapping fragment is alpha blended using an alpha of 0.5 (or maybe of decreasing alpha, so e.g. 2nd fragment is 0.5, 3rd is 0.33, 4th is 0.25 so we favor preserving further fragments information).

So AFAICT, this shader would alpha blend like a normal transparent shader, except that it doesn't blend/interact with anything but itself. How to do that?

I have little experience with shaders but am comfortable if I know where to read. So I'd really appreciate it if someone could point me in the direction I can look to create such a shader. The project is using Unity at the moment but I don't think that changes the approach to this problem.

***Update*:** After clarifying some thoughts I realize that the approach described above wouldn't be the most suitable solution in my case. This is because I forgot to emphasize that the most important thing is to visualize geometry within a proximity around the player, and that current approach would potentially obscure too much of the players view if there is a lot of layers drawn in front, and it would also look a bit too "busy" in general; the player should probably prefer to just know the information most relevant to him and nothing that is relatively far away. So instead I think the blending should be most x-ray view for geometry within close proximity to the player, and fade out to the foreground as it gets more distant.

# Answer
> 2 votes
I can think of a way to do this in two passes with a floating point render target initialized to black:

Pass 1: use additive blending into the render target with depth testing/writing off; write your colour to the RGB channel and 1 to the alpha channel.

Pass 2: read the previous contents of the render target, and divide the RGB values by the alpha value, outputting the result as an opaque colour (no blending).

For pixels written to only once, this is basically a no-op and just gives the original colour you wrote. For pixels written to multiple times, this gives the average colour, with each write given an equal weighting. That matches your 1, 0.5, 0.33, 0.25 weight series.

This second pass can be the one that writes into your original scene, with depth testing/writing enabled to clip out any occluded parts of this object.

---
Tags: unity, shaders
---


# Question
Title: New to Godot having problem understanding Button Group
I'm having an issue trying to understand the ButtonGroup logic, totally new to GDScript, don't have a clue of what I'm doing. Obviously is wrong.

I created a scene that I saved in a folder called "Interface", here is how it looks. Sorry, I know it's probably messy:

---

---

The scene is called "MenuButtons" and it looks as follow:

---

---

The GDScript attached to the scene looks as follow:

---

```
extends Control

export(ButtonGroup) var group

func _ready():
    print(group.get_buttons())
    for i in group.get_buttons():
        i.connect("pressed", self, "button_pressed")

func button_pressed():
    var pressed_button = str(group.get_pressed_button())
    var split_text = pressed_button.split(':')
    var button_method = str(split_text[0])
    print(button_method)

    if button_method == "NewGameButton": print('Restarting the game')
    if button_method == "OptionsButton": print('Opening the Options screen')
    if button_method == "ExitButton": print('Quiting the game')

```

---

When I execute the scene with F6 everything works as expected:

---

---

Still not what I'm expecting, but it prints something. But here is the situation, I instantiated the MenuButtons scene as a node in another scene called GameOverlay, which is the test game UI.

---

---

This scene as well is instantiated inside the Level Scene.

---

---

When the Level is run and the Game Over screen shows, neither group.get\_buttons() method returns a list and of course the buttons do not initiate the events. It seems to me that the script from MenuButtons does not recognize the button group at all.

---

---

I was following two tutorials trying to match their insight about using buttons in Godot. Yeah, I have no idea what I'm doing as you can tell. Any help would be really appreciated.

These are the tutorials I'm following:

1. GODOT Menu System tutorial using button themes 20 lines of code
2. How to use a Button Group - Godot Engine

# Answer
> 1 votes
I'm to sidestep the question a little, because I'm going to suggest to not use `ButtonGroup` at all.

---

First, why not `ButtonGroup`?

For what I understand the `BaseButton`s register themselves with the `ButtonGroup`, but the `ButtonGroup` is local to the scene by default, and that is problematic when nesting the scene inside of another one.

We can implement the functionality of your code without `ButtonGroup` at all, and I don't think these kind of menu needs a `ButtonGroup` at all.

*`ButtonGroup` prevents multiple buttons to stay pressed at the same time (think radio buttons or mutually exclusive toggle buttons), but that is not necessary if the buttons cannot stay pressed.*

---

First, we want to connect the `pressed` signal of the `BaseButton`s from code. We already have a container `MenuVContainer`, let us use it:

```
extends Control

func _ready() -> void:
    for i in get_node("MenuVContainer").get_children():
        var button := i as BaseButton
        if is_instance_valid(button):
            button.connect("pressed", self, "button_pressed")

```

Here we are iterating over all the children of `MenuVContainer`. And we will try to cast them as `BaseButton` with `i as BaseButton` (which results in `null` if it wasn't a `BaseButton`, thus checking if the instance is valid allows us to skip anything that isn't a `BaseButton`). And, of course, we connect the signal.

Ah, next you want to know which button was pressed. Ok, no matter, we are going to bind that on the signal connection, like this:

```
extends Control

func _ready() -> void:
    for i in get_node("MenuVContainer").get_children():
        var button := i as BaseButton
        if is_instance_valid(button):
            button.connect("pressed", self, "button_pressed", [button])

```

And now `button_pressed` will get it as a parameter:

```
extends Control

func _ready() -> void:
    for i in get_node("MenuVContainer").get_children():
        var button := i as BaseButton
        if is_instance_valid(button):
            button.connect("pressed", self, "button_pressed", [button])

func button_pressed(pressed_button:BaseButton) -> void:
    pass

```

And, of course, you can check which one you got a do something accordingly:

```
extends Control

func _ready() -> void:
    for i in get_node("MenuVContainer").get_children():
        var button := i as BaseButton
        if is_instance_valid(button):
            button.connect("pressed", self, "button_pressed", [button])

func button_pressed(pressed_button:BaseButton) -> void:
    var button_method := pressed_button.name
    if button_method == "NewGameButton": print('Restarting the game')
    if button_method == "OptionsButton": print('Opening the Options screen')
    if button_method == "ExitButton": print('Quiting the game')

```

Here `match` would work too:

```
extends Control

func _ready() -> void:
    for i in get_node("MenuVContainer").get_children():
        var button := i as BaseButton
        if is_instance_valid(button):
            button.connect("pressed", self, "button_pressed", [button])

func button_pressed(pressed_button:BaseButton) -> void:
    match pressed_button.name:
        "NewGameButton":
            print('Restarting the game')
        "OptionsButton":
            print('Opening the Options screen')
        "ExitButton":
            print('Quiting the game')

```

---

You could even call methods by those names:

```
extends Control

func _ready() -> void:
    for i in get_node("MenuVContainer").get_children():
        var button := i as BaseButton
        if is_instance_valid(button):
            button.connect("pressed", self, "button_pressed", [button])

func button_pressed(pressed_button:BaseButton) -> void:
    if has_method(pressed_button.name):
        call(pressed_button.name)

func NewGameButton() -> void:
    print('Restarting the game')

func OptionsButton() -> void:
    print('Opening the Options screen')

func ExitButton() -> void:
    print('Quiting the game')

```

Wait, if we are calling methods, why not connect them directly? You still have to write what happens for each button anyway.

```
extends Control

func _ready() -> void:
    get_node("MenuVContainer/NewGameButton").connect("pressed", self, "NewGameButton")
    get_node("MenuVContainer/OptionsButton").connect("pressed", self, "OptionsButton")
    get_node("MenuVContainer/ExitButton").connect("pressed", self, "ExitButton")

func NewGameButton() -> void:
    print('Restarting the game')

func OptionsButton() -> void:
    print('Opening the Options screen')

func ExitButton() -> void:
    print('Quiting the game')

```

If we are connecting buttons to methods. Why not do that from the editor?

For each button go to the Node panel and then on the Signals tab, double click "pressed", and then select the root node of you scene (the dialog also allows you to change the name of the method it will connect the signal to and set other settings). And you will end up with code that looks like this:

```
extends Control

func _on_NewGameButton_pressed() -> void:
    print('Restarting the game')

func _on_OptionsButton_pressed() -> void:
    print('Opening the Options screen')

func _on_ExitButton_pressed() -> void:
    print('Quiting the game')

```

Yes, do the default thing.

---
Tags: gui, godot, instancing, menu
---


# Question
Title: Perpendicular inelastic joint of two bodies in PyBox2d
I would like to create two objects of different density and (inelastically) weld them perpendicular together, so that the final object forms an L. Afterwards, I want to be able to assign a position and velocity to the newly welded object.

I tried to use `CreateWeldJoint` in the example below. However, I am not sure how to use it correctly and so far I didn't find any useful information. What I have so far looks as follows:

The image shows, that the joint of both bodies is not completely inelastic.

How can I use `CreateWeldJoint` or some other method, to weld two objects together at a 90 angle? How can I make the weld / joint completely inelastic?

```
from Box2D.examples.framework import Framework, main
from Box2D import b2EdgeShape, b2FixtureDef, b2PolygonShape

class TestObject(Framework):

    def __init__(self):
        super(TestObject, self).__init__()

        # World
        self.world.gravity = (0.0, 0.0)

        self.world.CreateStaticBody(
            shapes=[
                    b2EdgeShape(vertices=[(-10, 0), (10, 0)]),
                    b2EdgeShape(vertices=[(-10, 0), (-20, 20)]),
                    b2EdgeShape(vertices=[(10, 0), (20, 20)]),
                ]
        )

        obj_vertices = [(1.0, 1.0), (-1.0, 1.0), (-1.0, -1.0), (1.0, -1.0)]
        velocity = (0.0, -10.0)

        # First object
        height = 4
        width = 1

        obj1 = self.world.CreateDynamicBody(position=(15, 20), linearVelocity=velocity)
        obj1_vertices = [(width * item[0], height * item[1]) for item in obj_vertices]
        obj1_shape = b2PolygonShape(vertices=obj1_vertices)
        obj1_fixture_def = b2FixtureDef(shape=obj1_shape, density=1)
        _ = obj1.CreateFixture(obj1_fixture_def)

        # Second object
        height = 2
        width = 1

        obj2 = self.world.CreateDynamicBody(position=(15, 16), linearVelocity=velocity)
        obj2_vertices = [(width * item[0], height * item[1]) for item in obj_vertices]
        obj2_shape = b2PolygonShape(vertices=obj2_vertices)
        obj2_fixture_def = b2FixtureDef(shape=obj2_shape, density=10000)
        _ = obj2.CreateFixture(obj2_fixture_def)

        # Weld both objects
        obj_welded = self.world.CreateWeldJoint(
            bodyA=obj1,
            bodyB=obj2,
            localAnchorA=(0, -7),
            # localAnchorB=(0, -4),
            # referenceAngle=90,   # does not work
            # frequencyHz=0.0,
            # dampingRatio=0.0,
        )
        # obj_welded.CreateFixture(b2FixtureDef(position=(0, 40), linearVelocity=(0, 0)))   # does not work

    def Step(self, settings):
        super(TestObject, self).Step(settings)

if __name__ == "__main__":
    main(TestObject)

```

# Answer
It is actually pretty straight forward to connect two objects of different masses.

The following modified code shows how to create a single physics body to which two collider fixtures are attached:

```
from Box2D.examples.framework import Framework, main
    from Box2D import b2EdgeShape, b2FixtureDef, b2PolygonShape

    class TestObject(Framework):

        def __init__(self):
            super(TestObject, self).__init__()

            # World
            self.world.gravity = (0.0, 0.0)

            self.world.CreateStaticBody(
                shapes=[
                        b2EdgeShape(vertices=[(-10, 0), (10, 0)]),
                        b2EdgeShape(vertices=[(-10, 0), (-20, 20)]),
                        b2EdgeShape(vertices=[(10, 0), (20, 20)]),
                    ]
            )

            obj_vertices = [(1.0, 1.0), (-1.0, 1.0), (-1.0, -1.0), (1.0, -1.0)]
            velocity = (0.0, -10.0)

            # First object
            height = 4
            width = 1

            obj1 = self.world.CreateDynamicBody(position=(15, 20), linearVelocity=velocity)
            obj1_vertices = [(width * item[0], height * item[1]) for item in obj_vertices]
            obj1_shape = b2PolygonShape(vertices=obj1_vertices)
            obj1_fixture_def = b2FixtureDef(shape=obj1_shape, density=1)
            _ = obj1.CreateFixture(obj1_fixture_def)

            # Second object
            height = 2
            width = 1

            obj2_vertices = [(width * item[0], height * item[1]) for item in obj_vertices]
            obj2_shape = b2PolygonShape(vertices=obj2_vertices)
            obj2_fixture_def = b2FixtureDef(shape=obj2_shape, density=10000)
            _ = obj1.CreateFixture(obj2_fixture_def)

        def Step(self, settings):
            super(TestObject, self).Step(settings)

    if __name__ == "__main__":
        main(TestObject)

```
> 1 votes

---
Tags: box2d, python
---


# Question
Title: Why process physics before the variable framerate update in a game loop?
As far as I know, most game loops are executed in the following order:

1. Process user input
2. Update (once per frame)
3. Physics (also known as `fixedUpdate`, 0 to N times per frame)
4. Rendering

You can find the execution order of the Unity game loop here: https://docs.unity3d.com/Manual/ExecutionOrder.html

Unity's game loop is different in that `fixedUpdate` is executed earlier than `update`, is there any benefit to this when designing a game loop?

Additional information: I'm not familiar with Unity, but I'm making a platformer game that mimics the execution order of Unity's game loop. I have found that if the update is later than physics, the rendering will lag significantly in responding to user input. If the physics fps is set lower (i.e. timestep is set higher), the lag is more significant. How does the Unity game solve this problem?

# Answer
> 1 votes
Executing the game logic after the physics and before rendering the frame allows the game logic to react to physics events before they are being rendered.

For example, when the physics engine moved an object into an area where it is supposed to be destroyed, then the game logic has the opportunity to destroy that object before it gets rendered in that invalid location.

Further, Unity is able to run the physics simulation with a much lower update rate than the FPS. In that case it offers the options to either interpolate or extrapolate rigidbody positions (which is a setting on the Rigidbody component) to smooth out the rendering of their motions. This smoothing happens before Update. So the Update method can access the interpolated/extrapolated object positions before the rendering happens. This is particularly important if you want to synchronize non-rigidbody objects with rigidbodies (e.g. `transform.position = followedObject.transform.position`). This needs to happen before rendering and with interpolated/extrapolated positions, or the objects won't be properly synchronized.

So by running the Unity Update-method just before the rendering guarantees that all the `transform.position`s and `transform.rotation`s you check during it will actually be those which will appear on the screen...

...almost. There is still the animation system which runs before the rendering. The reason why the animation system gets processed after Update but before rendering is because you often want to set animation parameters in Update which you then want to be reflected in the current frame and not the next one.

But if you want to do something with the objects after the animation system was resolved, Unity still has you covered. You can use `LateUpdate` for that purpose.

---
Tags: unity, physics, game-loop
---


# Question
Title: How can I protect against a cheater changing variables on the client?
I built a multiplayer fighting game with *impactjs, socket.io* and *nodejs* and faced with "change variables hack" (I want to call it like this). All my current logic with jump, running, shoot etc. is running on frontend, socket and nodejs just for creating a room.

How can I protect against a cheater changing variables on the client?

If you can share with code loke this it will be great :)

# Answer
This won't prevent all cheating but at least will make it harder for the average cheat engine/ change variable hack. Follow the simple advise: **Don't trust the client**.

Now what does that mean? Usually those hacks are about either freezing variables (your health does not go down when hit) or increasing them (money, ammo, consumables). This works in games where we trust the client to hold all important logic and variables. So we don't use that at the server. All the client should send is Player got hit by whom and from what. It is now the servers job to verify and do the math. Is the hit bringing down enough health to kill the player? Did the attacker had the ressource to make the attack? Once verified, the server would sent the result back and the games continue. You can still use the client as a prediction for players that don't cheat. But it can happen that a few frames later you would need to revert when the true state comes from the server.

Now this won't prevent players who are using aim bots, view hacks, manipulating hit boxes or similar. But those are way harder to code compared to simply changing variables. If you want/ need to verify as well the physics, you do not need to render the full canvas on your server. Most of the time it is possible to run it in a `headless mode` or `server mode`.
> 3 votes

---
Tags: javascript, html5, browser-based-games, node.js, websocket
---


title: Is there any solution for skill merger?

text:
# Question
Title: Is there any solution for skill merger?
I'm trying to write a litrpg and one of the main feature is skill merger. Skill merger is a feature where characters can merge skills to create new skills (e.g. Fire ball + Sticky ball = Sticky fire ball).

Depending on the skill, a skill merger can happen anything between 1 to 9 times one at a time or at all once and only maxed proficiency skills are eligible for skill merger.

The new skill resulted from skill merger will retain its previous properties and effects whole also getting new properties and effects (e.g. Sticky fire ball can explode like normal fire ball and scatter like granade afterwards but sticks on things like burning gel and explosion will become quite unlike fire ball where it's a fast explosion damage or sticky ball just sticks and traps people).

So here's the problem I'm facing as a result of max proficiency skills can be eligible for skill merger. It kinda slows down that skill merger a lot.

A character will have 6 skill points per level so at level 9 they will have like 54 skills. Which resulting in slow skill merger but many skills.

Since it takes time to increase a skills proficiency to 100%. So it will take time for skill merger to be eligible in early levels.

By the way skill points are points that characters can you to get skills.

So is there any solution for this dilemma?

Sorry for misunderstanding.

# Answer
> 2 votes
One solution would be to have different skills require different amounts of work to get to 100% proficiency. When some skills max out very quickly, then it won't take very long until the first merger options become available.

This of course puts a limit on how far certain skills can be developed. How committed are you to the idea that a skill **must** be maxed out before it unlocks a merged skill? You could already enable certain skill mergers on earlier proficiency. For example, a character would already gain the option to learn Sticky Fireball with Fireball 30% and Stick Ball 40%.

If you do want to stay committed to the idea that mergers may only happen when a skill is maxed out, want mergers to happen early but also want to give the option to invest a lot of effort into mastering the art of fireballing, then you could solve that by also unlocking a more advanced version of a skill when it's maxed out. For example, when the character reached 100% proficiency in Fireball, they don't just unlock the merger with Stick Ball, but also unlock a new skill "Greater Fireball". Greater Fireball is basically just a stronger version of Fireball which also requires a lot more effort to bring to 100% proficiency.

That would mean that raising a skill to 100% gives two different progression options: diversification (by investing in a merged skill) or specialization (by investing in an advanced version of the same skill).

---
Tags: game-design
---


title: Shadowmapping in view space

text:
# Question
Title: Shadowmapping in view space
UV coordinates for shadow mapping are usually calculated from world position. I want to make it compliant with my screen space reflection (SSR) pipeline which works in view space.

Is it possible to calculate the shadow map uv coordinate from a recovered viewspace position?

Currently, I'm retrieving the viewspace position for my lighting made compliant with SSR using viewspace normals. Now I would like to use the same viewspace position to calculate the uv coordinates for shadow maps (and especially shadow cubemaps).

Alternatively, I've started to write an SSR pipeline starting with world space data, but it is slower probably because I have to use a `mul(float4, matrix)` to get back the world position. In view space the calculation is shorter, with a single appropriate `float4` for my `InvProj` matrix.

# Answer
I got it for directional shadowmaps in deferred mode. At the end as we need to perform a last multiplication with the shadow matrix projection I find it simpler for deferred rendering to start from screen space

```
 float4 SPos = mul(float4(uv.x*2-1, 1- uv.y*2, Depth, 1), InvSceneViewProj_LightViewProj);
 SPos.xy=mad(SPos.xy/SPos.w, float2(0.5,-0.5),float2(0.5,0.5);
 float S = shadowmap.Sample(clamp, SPos.xy).r+bias;
 Shadow = (S*SPos.w < SPos.z)?0.5:1;//avoid divide SPos.z/SPos.w

```

where Depth comes from the scene depth buffer and InvSceneViewProj\_LightViewProj is the concatenation store in the constant buffer of Inverse(View\*Proj) for the scene with ViewProj for the directional light, an adaptation of the comments

After revising this answer I finally can also directly use the position in view space. A lack of attention in my matix stteings. The SPos line becomes:

```
  float4 SPos = mul(PosViewSpace, InvSceneView_LightViewProj);

```

I guess both calculs have the same gpu cost.
> 0 votes

# Answer
In any form of shadow mapping, you need to multiply by a matrix (stored as a uniform variable or looked up from a buffer) representing the light's point of view and projection.

If that matrix is currently set up to accept an input in world space, and you want the input to be expressed in view space instead, then all you have to do is one extra matrix multiply outside the shader when you populate that uniform / buffer:

```
mat4x4 lightFromView = light.viewProjectionMatrix * camera.viewToWorldMatrix;

```

This concatenates the two matrices into one, so inside your shader, the single matrix multiplication that you were going to do *anyway* does both jobs: mapping the camera view space point to world space, and mapping that world space point to the light's projected space.
> 0 votes

---
Tags: hlsl, shadow-mapping
---


title: Collider overlap is not being detected

text:
# Question
Title: Collider overlap is not being detected
I am writing some logic to handle spawning objects into a game scene at a randomly generated location based on the size of a collider's bounds. The logic for getting the coordinates and instantiating an object in the corresponding location is working fine but I have logic I use to make sure that the object being placed is not colliding with any other colliders. To detect if the gameobject I have placed is colliding with anything I am using `Physics2D.OverlapCollider()`, passing in the collider of the gameobject. I get no colliders back though. Below is a simplified version of what I'm doing:

```
var x = UnityEngine.Random.Range(xmin, xmax);
var y = UnityEngine.Random.Range(ymin, ymax);
var spawnedObjCollider = spawnedObj.GetComponent<Collider2D>();
spawnedObj.transform.position = new Vector3(x, y, 0f);
Physics2D.SyncTransforms();

var overlappingColliders = new List<Collider2D>();
var numColliders = Physics2D.OverlapCollider(spawnedObjCollider, new ContactFilter2D().NoFilter(), overlappingColliders);

```

In the case that I'm looking at, the spawned gameobject is overlapping another collider but it acts like it doesn't see it. Both objects are on the default layer even though it shouldn't matter what layer they are on since I am passing in NoFilter(). (the small collider is the collider of the spawned object):

These are the collider settings, at runtime, for the spawned gameobject:

These are the collider settings, at runtime, for the collider that the spawned gameobject is being put on top of:

# Answer
I must not have had Physics2D.SyncTransforms(); set correctly in my code after the position was changed. Adding that seemed to fix the issue.
> 0 votes

---
Tags: unity, collider
---


# Question
Title: Tiling perlin noise seamlessly, but without repeating to generate an infinite 3D world
I have been working on a 3D game in java using LWJGL for a while now. I am trying to make procedurally generated infinite 3D terrain that is generated around the player.

So far I have:

* 3D terrain chunks that are loaded and unloaded when the player moves. These chunks are made up of triangles not quads, and are 128x128 vertices.
* A Perlin noise class that can successfully generate Perlin noise. (I think it is actually something called value noise, but it works)
* A world class that handles loading and unloading of chunks, and applying the height maps to the chunks.

All of this works as it is coded to do, but not how I want it to. I don't know how to tile the noise seamlessly.

How would I make the noise tile, and furthermore, how would I generate large structures such as mountains that occupy probably up to hundreds of chunks.

Here is what is currently happening with the chunks and noise not tiling:

Here is my Perlin noise code:

```
private float[][] perlinNoise(int width, int height, int octave, float[][] whiteNoise)
{
    float[][] result = new float[width][height];

    int samplePeriod = 1 << octave;
    float sampleFrequency = 1.0f / samplePeriod;

    for (int i = 0; i < width; i++)
    {
        int x1 = (i / samplePeriod) * samplePeriod;
        int x2 = (x1 + samplePeriod) % width;
        float xBlend = (i - x1) * sampleFrequency;

        for (int j = 0; j < height; j++)
        {
            int y1 = (j / samplePeriod) * samplePeriod;
            int y2 = (y1 + samplePeriod) % height;
            float yBlend = (j - y1) * sampleFrequency;

            float top = (float) MathHelper.interpolateLinear(whiteNoise[x1][y1], whiteNoise[x2][y1], xBlend);

            float bottom = (float) MathHelper.interpolateLinear(whiteNoise[x1][y2], whiteNoise[x2][y2], xBlend);

            result[i][j] = (float) MathHelper.interpolateLinear(top, bottom, yBlend);
        }
    }
    return result;
}

public float[][] generatePerlinNoise(int width, int height, Random random, int octaveCount)
{
    float[][] whiteNoise = new float[width][height];
    float[][][] totalNoise = new float[octaveCount][][];
    float[][] perlinNoise = new float[width][height];
    float amplitude = 1.0f;
    float totalAmplitude = 0.0f;
    float persistance = 0.5f;

    for (int i = 0; i < width; i++)
    {
        for (int j = 0; j < height; j++)
        {
            whiteNoise[i][j] = random.nextFloat() % 1;
        }
    }
    for (int i = 0; i < octaveCount; i++)
    {
        totalNoise[i] = perlinNoise(width, height, i, whiteNoise);
    }
    for (int o = octaveCount - 1; o >= 0; o--)
    {
        amplitude *= persistance;
        totalAmplitude += amplitude;

        for (int i = 0; i < width; i++)
        {
            for (int j = 0; j < height; j++)
            {
                perlinNoise[i][j] += totalNoise[o][i][j] * amplitude;
            }
        }
    }
    for (int i = 0; i < width; i++)
    {
        for (int j = 0; j < height; j++)
        {
            perlinNoise[i][j] /= totalAmplitude;
        }
    }
    return perlinNoise;
}

```

I think it would also be worth mentioning that I have asked about this on StackOverflow as well.

# Answer
> 5 votes
Given credit to Alan Wolfe for what he said on "INFINITELY tile". A 2d perlin noise (or a 2d simple noise) will have no seam problem as far as you stay away from noise borders (defined by floatin point dimenision) Referencing the image:

and said that you have chunks with 128X128 vertex, in chunk i,j you compute each vertex as :

```
for x : 0 .. 128-1
 for y : 0 .. 128-1
  PerlinNoise2d.getValue(i*128 + x, j*128 + y)

```

this , will grant seamless between chunks.

If you want to simulate a infinite world regardless of noise borders , you may use a 3d noise and consider the values on the surface of a sphere.. but this is another story.

# Answer
> 0 votes
I know this is super old, but the underlying implementations of both perlin noise and value noise are just grids that interpolate value fields between cells, so there are two possible options for fixes.

Given a system where you are trying to tile arbitrarily seeded Perlin maps, keep track of the values at the edge nodes for each octave of seeding and run an interpolation pass on a cell the size of the largest octave using the values at the edges of the two divergent maps (for all the smaller octaves excepting the largest you will have to generate all the intermediary values aside from the edge node values)

The alternative system is one where the address of the node informs the seeding (for example, when calculating my random numbers to populate the values for the node, I seed the random generator with something like `NodeSeed = GlobalSeed + x + ", " + y` In that case every node given the same x, and y will produce the same random value every time. With such a system I can calculate the interpolation overlap with my neighboring node given infinite possible values of x and y. So when I do my interpolation pass I calculate one row/column past the actual value I need for every octave and use that to calculate the interpolated values that will be accurate to the edges of the next cell when I get around to generating it.

---
Tags: java, 3d, procedural-generation, terrain-rendering, perlin-noise
---


# Question
Title: How to insert a new control point on 3D cubic Bézier spline, without deforming current shape?
I have a spline generation system using a cubic Bézier algorithm.

I created a tool that splits the spline and adds a new point where the user clicked on the spline, but it causes the spline to deform from its current shape.

How can I calculate Bézier control point positions in 3D space to avoid deformation, as software like 3ds Max and Blender do?

# Answer
What you're looking for is called "de Casteljau's algorithm"

First, you need to find the segment and the parameter value \\$t\\$ at the point that was clicked. Search "closest point on cubic Bézier spline" for algorithms to find that.

Now you have a segment with control points \\$\\{ P\_1, P\_2, P\_3, P\_4 \\}\\$ and a parameter value \\$0 \< t \< 1\\$ (if \\$t\\$ is exactly zero or one, then control point \\$P\_1\\$ or \\$P\_4\\$ respectively already split the spline at the clicked point), at which the Bézier segment passes through the clicked point \\$P\_t\\$.

We can now form new points by interpolating between the existing control points by a factor of \\$t\\$:

$$ P\_5 = (1 - t) P\_1 + t P\_2\\ P\_6 = (1 - t) P\_2 + t P\_3\\ P\_7 = (1 - t) P\_3 + t P\_4\\ $$

and again:

$$ P\_8 = (1 - t) P\_5 + t P\_6\\ P\_9 = (1 - t) P\_6 + t P\_7\\ $$

(If we wanted, we could also find \\$P\_t = (1 - t) P\_8 + t P\_9\\$ this way, but by this stage you probably already know it)

Your two new Bézier segments are:

$$ \\{P\_1, P\_5, P\_8, P\_t\\}\\ \\{P\_t, P\_9, P\_7, P\_4\\} $$
> 1 votes

---
Tags: linear-algebra, beziers, splines
---


# Question
Title: Compute the difference between two vector3 and iterate with the difference in mathematically
I have two eularAngle vector3 A , and vector3 B;

I want to rotate the vector3 A rotate to vector3 B by 10 small steps;

```
for (int i = 0; i < 10; i++)
        {
            yield return new WaitForSeconds(0.02f);
            float progress = (i + 1) / (float)10;
            tarGet.transform.eulerAngles = Vector3.Slerp(A, B, progress);

        }

```

I know it can use lerp to achieve this， but I need to know how this is done mathematically. like this

```
Vecctor3 C = B - A;
for (int i = 0; i < 10; i++)
        {
            yield return new WaitForSeconds(0.02f);
            B += C/10;

        }

```

# Answer
Yes you can:

So you have 2 vectors:

```
 Vector3 A = new Vector3(7,5,6);
 Vector3 B = new Vector3(3,18,-46);

```

Now lets get those 10 intermediate vectors:

```
Vector3 C = B-A;
Vector3 d1 = (A+((C/10)*1)).normalized*A.magnitude;
Vector3 d2 = (A+((C/10)*2)).normalized*A.magnitude;
Vector3 d3 = (A+((C/10)*3)).normalized*A.magnitude;
Vector3 d4 = (A+((C/10)*4)).normalized*A.magnitude;
Vector3 d5 = (A+((C/10)*5)).normalized*A.magnitude;
Vector3 d6 = (A+((C/10)*6)).normalized*A.magnitude;
Vector3 d7 = (A+((C/10)*7)).normalized*A.magnitude;
Vector3 d8 = (A+((C/10)*8)).normalized*A.magnitude;
Vector3 d9 = (A+((C/10)*9)).normalized*A.magnitude;
Vector3 d10= (A+((C/10)*10)).normalized*A.magnitude;

```

now you can rotate A incrementally using something like this in your procedure:

```
A=d1;
yield return new WaitForSeconds(0.02f);
A=d2;
yield return new WaitForSeconds(0.02f);
A=d3;
yield return new WaitForSeconds(0.02f);
A=d4;
yield return new WaitForSeconds(0.02f);
A=d5;
yield return new WaitForSeconds(0.02f);
A=d6;
yield return new WaitForSeconds(0.02f);
A=d7;
yield return new WaitForSeconds(0.02f);
A=d8;
yield return new WaitForSeconds(0.02f);
A=d9;
yield return new WaitForSeconds(0.02f);
A=d10;
yield return new WaitForSeconds(0.02f);

```
> -1 votes

---
Tags: unity, mathematics, vector
---


title: How to pass voxel data to shader?

text:
# Question
Title: How to pass voxel data to shader?
I am working on a voxel game, and I approached the point where I need to add day/night in my world. Apparently, I should just be able to pass the torch and sunlight values into my shader and multiply the sunlight variable by the amount of sunlight I have.

I have no idea how to do this. I know you can only pass the same variables for all vertex/fragments, but how can you pass an entire array of voxel data into a shader?

* How would I know what voxel data is seen by the shader, and what data is not?
* Most importantly: **how does each fragment know what voxel corresponds to it when the shader only has a knowledge of its 2D placement on the screen?**

# Answer
> 1 votes
> I know you can only pass the same variables for all vertex/fragments, but how can you pass an entire array of voxel data into a shader?

Here's some methods I can think of:

1. As part of the vertices. This means you have to rewrite the vertices whenever the block lighting changes (but time of day can be handled by a uniform, via the multiplication you mentioned).
2. In a *3D texture* that stores the light value in a texel for each. This requires storing a lot of invisible data, but it is cheap per block.
3. In a *buffer*, organized in whatever format you like. (In OpenGL I believe it would be a “SSBO” specifically, but I haven't used that myself.) For example, you could assign a unique number to each currently visible block surface, put that number in the vertices, and use it as an index to look up the light for that surface in an array stored in the buffer. That would store data efficiently in memory but require lots of bookkeeping.

I've personally used option 2 with some success, but I haven't tried option 3. Option 1 requires lots of mesh updates and isn't good for “smooth” lighting.

All three of these options are, in some way, providing the data as some kind of large array to the shader. Such things are always some kind of explicitly-created GPU object separate from simple `glUniform`s, which you will have to update as the world is modified.

> does each fragment know what voxel corresponds to it when the shader only has a knowledge of its 2D placement on the screen?

You can pass any information you want from the vertex shader to the fragment shader. That can be the 3-dimensional voxel position, or it could be the light data already fetched from wherever you stored it.

In my implementation I pass voxel coordinates from the vertex shader to the fragment shader, and have the fragment shader look up the values in the light data texture.

---
Tags: shaders, glsl, voxels, fragment-shader, array
---


# Question
Title: How can I stop the Unreal Editor's UI from being blurry?
My Unreal Engine UI does not look sharp and is blurred on my 1080p monitor. Subsequently, the viewport is slightly blurry and edges are jagged. I have changed the setting of the viewport to "Cinematic," yet this still persists.

I have two images available where the first is mine and as you can see, the image is slightly blurred and text on the left-hand side is not sharp.

The second image is from a YouTube video which has been compressed (by YouTube) yet it still looks better.

How can I make the UI more crisp and prevent the blurring?

Anyone?

# Answer
Being the clever piece of software it is, when UE4 is inactive for a certain amount of time- or more specifically if the frame rate of the editor has been below a certain threshold for a certain amount of time (if you've been editing the open level, blueprints or code as opposed to running your game in the editor for example) it automatically lowers the visual quality of what is displayed in the editor to save on CPU processing power. Note that this feature does not effect UI elements such as buttons and text and the like. Your editor can also appear like this straight off the bat, if you are loading a project that you have had open previously, where the frame rate of the editor was below the set threshold for an extended period, prior to you closing the editor.

Generally it will display a pop up briefly first giving you the opportunity to cancel the change, but if you ignored it or didn't see it (if you had switched out to your browser briefly perhaps or went and made yourself a sandwich) then the changes will be applied. Out of curiosity which version of UE4 are you running?

I"m running 4.14 and it automatically reverts the resolution and other quality settings to normal as soon as I click on an object within the editor, however it may not revert automatically on earlier versions, I'm not sure. In any event you can change it back manually by adjusting the Scalability settings- just click on the 'Settings' drop down above the editor, and select 'Scalability Settings'. You can also change the quality of the materials displayed in the editor and the preview rendering level with the two settings directly below if they are set lower than expected, but the scalability settings is usually the culprit.

I've included a link to Epics documentation on Scalability Settings so that you can read more about this feature, and make informed choices about the settings you adjust as opposed to taking a shot in the dark, however if you haven't already try clicking a few objects inside your level first, or perhaps simulating play mode to see if the settings revert automatically.

Note also that you can turn off this feature in the dialogue box that pops up in the future, or by unchecking the 'Monitor Engine Performance' in the scalability settings menu, though now that you know how and why it happens (assuming this post resolved your issue), it's probably better not to as it's pretty damn nifty in my opinion. I hope that helps!
> 3 votes

# Answer
I would check if you don't have display scaling activated.
> 1 votes

---
Tags: unreal-4
---


# Question
Title: How to reconnect a client to a match (not the server)
In a multiplayer client-server Unity project using Mirror networking, I have a matchmaking system where the server matches two players and gives them a `MatchID`.

The game is server-side authenticated, each player has a unique ID, each match has its own MatchID, and everything is available on the server.

Everything works fine, except when someone gets disconnected.

I can't find any tutorial or documentation on **how to reconnect a client to a match** with a `MatchID`. All the shared `GameObjects` need to be recreated on the client with the correct `netIdentity` and authorities

How can I go about reconnecting, or setting up `NetworkIdentity` components in the ways above?

# Answer
It is a while since I made a reconnect with Mirror, here is roughly what I did:

1. The server is storing a map of the players authetication as key, the value is everything that was tied to the player (matchId, roomId, NetworkConnection, etc), is basically just identifing that the reconnected player is the same one as a previous one. Docu
2. In the Networkmanager you usually overwrite the `OnServerAddPlayer(NetworkConnection conn)`. You can grab authentication and compare if it is a new player or reconnected from 1)
3. You call the `NetworkServer.ReplacePlayerForConnection` with your needed parameters. This replaces the player object for a connection with a different player object. The old player object is not destroyed. If a connection already has a player object, this can be used to replace that object with a different player object.

I can't find my old code currently, not sure if that was all that was needed or if I had to clean up some duplicated objects. Once I found it or recoded it, I will add some proof of work. Feel free to add your own answer if you get it working before that
> 1 votes

---
Tags: unity, c#, mirror-networking
---


# Question
Title: What torque should I apply in Bullet to maintain a vertical orientation?
I have a `RigidBody` in Bullet. Each frame, I want to apply torque to correct its orientation toward an upright position (i.e. near-zero pitch and roll). I know its angular velocity and orientation.

Bullet is not very well documented. I don't even know what the parameters to `btRigidBody::applyTorque()` mean.

How should I approach this?

# Answer
This is a classical control problem. You want to create a feedback loop that takes the divergence from optimal position and applies the appropriate torque to nudge it back into position.

```
btQuaternion targetOrientation  = // whatever you need
btQuaternion currentOrientation = myObject->getOrientation();

```

Getting the delta orientation is quite simple, you need to find the "difference" between two the quaternions target and current orientation.

```
btQuaternion deltaOrientation = targetOrientation *  currentOrientation.inverse();

```

Unfortunately this quaterion does not say much about any divergence that we can use. But if you convert this delta orientation into euler angles.

```
btVector3 deltaEuler = QuaternionToEulerXYZ(deltaOrientation );

```

You basically get the scaled inverse of the torque you want to apply. Now you "just" need to find an appropriate amount to ease it in.

```
btVector torqueToApply = control(-deltaEuler);

```

The simple solution is to multiply it with a factor. You may need to play around with the factor until you find a good value.

```
// simple proportional controller
btVector control(btVector in)
{
    // play around with the factor until you find a matching one
    static Kp = 0.5;
    return in * Kp;
}

```

You may also want to look into a PID-Controller to get a smoother more responsive easing.
> 4 votes

# Answer
I approached with a little Googlesearch ;)

From what I found bt:RigidBody::applyTorque(btVector3 & torque) takes a vector **in WorldSpace** and uses it as axis to apply a torque which has a strength of the length of the vector.
The LocalSpace-Torque seems to be solved in this answer, even though the provided code looks like there has to be an easier version. The author confirms this.

To actually compute the torque needed to be applied, think of the following:

1. You have two phases:
    1. Acceleration - Apply Torque to increase rotation speed
    2. Decceleration - Apply Torque to decrease rotation speed (usually opposite of Acceleration-Torque)
2. Do you want a maximum rotation speed (for example to not make it immediatly visible that a Bullet is rotating)?
    1. Set Torque to 0 inbetween (or simply don't apply it).

You have to carefully time these phases, if you for example have a maximum Torque you can/want apply, accelerating too long will result in overshooting. Ideally your acceleration- and decceleration-Torque are of the same length along the same axis.

Rest is up to you, and I hope I could help.

**EDIT:** Long live the related question: changing orientation by applying torques.
> 1 votes

# Answer
The accepted answer works for me and is a good starting point.

It might be helpful to have a complete example that works with the most recent Bullet version.

```
btRigidBody* rigid_body;

btQuaternion current_orientation = bt_rigid_body->getOrientation();

btVector3 axis(0, 0, 1);
btScalar angle = 0.1;
btQuaternion target_orientation(axis, angle);

btQuaternion delta = target_orientation * current_orientation.inverse();

// Get Euler angles
float x, y, z;
delta.getEulerZYX(z, y, x);

// Feed torque into control function (see accepted answer)
btVector3 local_torque = control(btVector3(x, y, z));

// Transform torque to world space
btVector3 world_torque = bt_rigid_body->getWorldTransform().getBasis() * local_torque;
bt_rigid_body->applyTorque(world_torque);

```
> 1 votes

---
Tags: c++, physics, rotation, bullet-physics
---